V8 Project
maglev-ir.h
Go to the documentation of this file.
1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_MAGLEV_MAGLEV_IR_H_
6 #define V8_MAGLEV_MAGLEV_IR_H_
7 
8 #include <optional>
9 #include <type_traits>
10 
11 #include "src/base/bit-field.h"
12 #include "src/base/bits.h"
13 #include "src/base/bounds.h"
15 #include "src/base/enum-set.h"
16 #include "src/base/logging.h"
17 #include "src/base/macros.h"
18 #include "src/base/small-vector.h"
19 #include "src/base/threaded-list.h"
21 #include "src/codegen/label.h"
23 #include "src/codegen/reglist.h"
25 #include "src/common/globals.h"
26 #include "src/common/operation.h"
31 #include "src/compiler/heap-refs.h"
32 // TODO(dmercadier): move the Turboshaft utils functions to shared code (in
33 // particular, any_of, which is the reason we're including this Turboshaft
34 // header)
42 #include "src/objects/arguments.h"
45 #include "src/objects/smi.h"
47 #include "src/roots/roots.h"
49 #include "src/utils/utils.h"
50 #include "src/zone/zone.h"
51 
52 #ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
53 #define IF_UD(Macro, ...) Macro(__VA_ARGS__)
54 #else
55 #define IF_UD(Macro, ...)
56 #endif // V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
57 
58 namespace v8 {
59 namespace internal {
60 
61 enum Condition : int;
62 
63 namespace maglev {
64 
65 class BasicBlock;
66 class ProcessingState;
67 class MaglevAssembler;
68 class MaglevCodeGenState;
69 class MaglevCompilationUnit;
70 class MaglevGraphLabeller;
71 class MaglevVregAllocationState;
72 class CompactInterpreterFrameState;
73 class MergePointInterpreterFrameState;
74 class ExceptionHandlerInfo;
75 
76 // Nodes are either
77 // 1. side-effecting or value-holding SSA nodes in the body of basic blocks, or
78 // 2. Control nodes that store the control flow at the end of basic blocks, and
79 // form a separate node hierarchy to non-control nodes.
80 //
81 // The macro lists below must match the node class hierarchy.
82 
83 #define GENERIC_OPERATIONS_NODE_LIST(V) \
84  V(GenericAdd) \
85  V(GenericSubtract) \
86  V(GenericMultiply) \
87  V(GenericDivide) \
88  V(GenericModulus) \
89  V(GenericExponentiate) \
90  V(GenericBitwiseAnd) \
91  V(GenericBitwiseOr) \
92  V(GenericBitwiseXor) \
93  V(GenericShiftLeft) \
94  V(GenericShiftRight) \
95  V(GenericShiftRightLogical) \
96  V(GenericBitwiseNot) \
97  V(GenericNegate) \
98  V(GenericIncrement) \
99  V(GenericDecrement) \
100  V(GenericEqual) \
101  V(GenericStrictEqual) \
102  V(GenericLessThan) \
103  V(GenericLessThanOrEqual) \
104  V(GenericGreaterThan) \
105  V(GenericGreaterThanOrEqual)
106 
107 #define INT32_OPERATIONS_NODE_LIST(V) \
108  V(Int32AbsWithOverflow) \
109  V(Int32AddWithOverflow) \
110  V(Int32SubtractWithOverflow) \
111  V(Int32MultiplyWithOverflow) \
112  V(Int32DivideWithOverflow) \
113  V(Int32ModulusWithOverflow) \
114  V(Int32BitwiseAnd) \
115  V(Int32BitwiseOr) \
116  V(Int32BitwiseXor) \
117  V(Int32ShiftLeft) \
118  V(Int32ShiftRight) \
119  V(Int32ShiftRightLogical) \
120  V(Int32BitwiseNot) \
121  V(Int32NegateWithOverflow) \
122  V(Int32IncrementWithOverflow) \
123  V(Int32DecrementWithOverflow) \
124  V(Int32Compare) \
125  V(Int32ToBoolean)
126 
127 #define FLOAT64_OPERATIONS_NODE_LIST(V) \
128  V(Float64Abs) \
129  V(Float64Add) \
130  V(Float64Subtract) \
131  V(Float64Multiply) \
132  V(Float64Divide) \
133  V(Float64Exponentiate) \
134  V(Float64Modulus) \
135  V(Float64Negate) \
136  V(Float64Round) \
137  V(Float64Compare) \
138  V(Float64ToBoolean) \
139  V(Float64Ieee754Unary)
140 
141 #define SMI_OPERATIONS_NODE_LIST(V) \
142  V(CheckedSmiIncrement) \
143  V(CheckedSmiDecrement)
144 
145 #define CONSTANT_VALUE_NODE_LIST(V) \
146  V(Constant) \
147  V(Float64Constant) \
148  V(Int32Constant) \
149  V(Uint32Constant) \
150  V(IntPtrConstant) \
151  V(RootConstant) \
152  V(SmiConstant) \
153  V(TaggedIndexConstant) \
154  V(TrustedConstant)
155 
156 #define INLINE_BUILTIN_NODE_LIST(V) \
157  V(BuiltinStringFromCharCode) \
158  V(BuiltinStringPrototypeCharCodeOrCodePointAt) \
159  V(BuiltinSeqOneByteStringCharCodeAt)
160 
161 #define TURBOLEV_VALUE_NODE_LIST(V) \
162  V(CreateFastArrayElements) \
163  V(MapPrototypeGet) \
164  V(MapPrototypeGetInt32Key) \
165  V(SetPrototypeHas)
166 
167 #define TURBOLEV_NON_VALUE_NODE_LIST(V) V(TransitionAndStoreArrayElement)
168 
169 #define VALUE_NODE_LIST(V) \
170  V(Identity) \
171  V(AllocationBlock) \
172  V(ArgumentsElements) \
173  V(ArgumentsLength) \
174  V(RestLength) \
175  V(Call) \
176  V(CallBuiltin) \
177  V(CallCPPBuiltin) \
178  V(CallForwardVarargs) \
179  V(CallRuntime) \
180  V(CallWithArrayLike) \
181  V(CallWithSpread) \
182  V(CallKnownApiFunction) \
183  V(CallKnownJSFunction) \
184  V(CallSelf) \
185  V(Construct) \
186  V(CheckConstructResult) \
187  V(CheckDerivedConstructResult) \
188  V(ConstructWithSpread) \
189  V(ConvertReceiver) \
190  V(ConvertHoleToUndefined) \
191  V(CreateArrayLiteral) \
192  V(CreateShallowArrayLiteral) \
193  V(CreateObjectLiteral) \
194  V(CreateShallowObjectLiteral) \
195  V(CreateFunctionContext) \
196  V(CreateClosure) \
197  V(FastCreateClosure) \
198  V(CreateRegExpLiteral) \
199  V(DeleteProperty) \
200  V(EnsureWritableFastElements) \
201  V(ExtendPropertiesBackingStore) \
202  V(InlinedAllocation) \
203  V(ForInPrepare) \
204  V(ForInNext) \
205  V(GeneratorRestoreRegister) \
206  V(GetIterator) \
207  V(GetSecondReturnedValue) \
208  V(GetTemplateObject) \
209  V(HasInPrototypeChain) \
210  V(InitialValue) \
211  V(LoadTaggedField) \
212  V(LoadTaggedFieldForProperty) \
213  V(LoadTaggedFieldForContextSlotNoCells) \
214  V(LoadTaggedFieldForContextSlot) \
215  V(LoadDoubleField) \
216  V(LoadFloat64) \
217  V(LoadInt32) \
218  V(LoadTaggedFieldByFieldIndex) \
219  V(LoadFixedArrayElement) \
220  V(LoadFixedDoubleArrayElement) \
221  V(LoadHoleyFixedDoubleArrayElement) \
222  V(LoadHoleyFixedDoubleArrayElementCheckedNotHole) \
223  V(LoadSignedIntDataViewElement) \
224  V(LoadDoubleDataViewElement) \
225  V(LoadTypedArrayLength) \
226  V(LoadSignedIntTypedArrayElement) \
227  V(LoadUnsignedIntTypedArrayElement) \
228  V(LoadDoubleTypedArrayElement) \
229  V(LoadSignedIntConstantTypedArrayElement) \
230  V(LoadUnsignedIntConstantTypedArrayElement) \
231  V(LoadDoubleConstantTypedArrayElement) \
232  V(LoadEnumCacheLength) \
233  V(LoadGlobal) \
234  V(LoadNamedGeneric) \
235  V(LoadNamedFromSuperGeneric) \
236  V(MaybeGrowFastElements) \
237  V(MigrateMapIfNeeded) \
238  V(SetNamedGeneric) \
239  V(DefineNamedOwnGeneric) \
240  V(StoreInArrayLiteralGeneric) \
241  V(StoreGlobal) \
242  V(GetKeyedGeneric) \
243  V(SetKeyedGeneric) \
244  V(DefineKeyedOwnGeneric) \
245  V(Phi) \
246  V(RegisterInput) \
247  V(CheckedSmiSizedInt32) \
248  V(CheckedSmiTagInt32) \
249  V(CheckedSmiTagUint32) \
250  V(CheckedSmiTagIntPtr) \
251  V(UnsafeSmiTagInt32) \
252  V(UnsafeSmiTagUint32) \
253  V(UnsafeSmiTagIntPtr) \
254  V(CheckedSmiUntag) \
255  V(UnsafeSmiUntag) \
256  V(CheckedInternalizedString) \
257  V(CheckedObjectToIndex) \
258  V(CheckedTruncateNumberOrOddballToInt32) \
259  V(CheckedInt32ToUint32) \
260  V(CheckedIntPtrToUint32) \
261  V(UnsafeInt32ToUint32) \
262  V(CheckedUint32ToInt32) \
263  V(CheckedIntPtrToInt32) \
264  V(ChangeInt32ToFloat64) \
265  V(ChangeUint32ToFloat64) \
266  V(ChangeIntPtrToFloat64) \
267  V(CheckedTruncateFloat64ToInt32) \
268  V(CheckedTruncateFloat64ToUint32) \
269  V(TruncateNumberOrOddballToInt32) \
270  V(TruncateUint32ToInt32) \
271  V(TruncateFloat64ToInt32) \
272  V(UnsafeTruncateUint32ToInt32) \
273  V(UnsafeTruncateFloat64ToInt32) \
274  V(Int32ToUint8Clamped) \
275  V(Uint32ToUint8Clamped) \
276  V(Float64ToUint8Clamped) \
277  V(CheckedNumberToUint8Clamped) \
278  V(Int32ToNumber) \
279  V(Uint32ToNumber) \
280  V(Int32CountLeadingZeros) \
281  V(SmiCountLeadingZeros) \
282  V(Float64CountLeadingZeros) \
283  V(IntPtrToBoolean) \
284  V(IntPtrToNumber) \
285  V(Float64ToTagged) \
286  V(Float64ToHeapNumberForField) \
287  V(HoleyFloat64ToTagged) \
288  V(CheckedSmiTagFloat64) \
289  V(CheckedNumberToInt32) \
290  V(CheckedNumberOrOddballToFloat64) \
291  V(UncheckedNumberOrOddballToFloat64) \
292  V(CheckedNumberOrOddballToHoleyFloat64) \
293  V(CheckedHoleyFloat64ToFloat64) \
294  V(HoleyFloat64ToMaybeNanFloat64) \
295  IF_UD(V, Float64ToHoleyFloat64) \
296  IF_UD(V, ConvertHoleNanToUndefinedNan) \
297  V(HoleyFloat64IsHole) \
298  V(LogicalNot) \
299  V(SetPendingMessage) \
300  V(StringAt) \
301  V(StringEqual) \
302  V(StringLength) \
303  V(StringConcat) \
304  V(SeqOneByteStringAt) \
305  V(ConsStringMap) \
306  V(UnwrapStringWrapper) \
307  V(ToBoolean) \
308  V(ToBooleanLogicalNot) \
309  V(AllocateElementsArray) \
310  V(TaggedEqual) \
311  V(TaggedNotEqual) \
312  V(TestInstanceOf) \
313  V(TestUndetectable) \
314  V(TestTypeOf) \
315  V(ToName) \
316  V(ToNumberOrNumeric) \
317  V(ToObject) \
318  V(ToString) \
319  V(TransitionElementsKind) \
320  V(NumberToString) \
321  V(UpdateJSArrayLength) \
322  V(VirtualObject) \
323  V(GetContinuationPreservedEmbedderData) \
324  CONSTANT_VALUE_NODE_LIST(V) \
325  INT32_OPERATIONS_NODE_LIST(V) \
326  FLOAT64_OPERATIONS_NODE_LIST(V) \
327  SMI_OPERATIONS_NODE_LIST(V) \
328  GENERIC_OPERATIONS_NODE_LIST(V) \
329  INLINE_BUILTIN_NODE_LIST(V) \
330  TURBOLEV_VALUE_NODE_LIST(V)
331 
332 #define GAP_MOVE_NODE_LIST(V) \
333  V(ConstantGapMove) \
334  V(GapMove)
335 
336 #define NON_VALUE_NODE_LIST(V) \
337  V(AssertInt32) \
338  V(CheckDynamicValue) \
339  V(CheckInt32IsSmi) \
340  V(CheckUint32IsSmi) \
341  V(CheckIntPtrIsSmi) \
342  V(CheckHoleyFloat64IsSmi) \
343  V(CheckHeapObject) \
344  V(CheckInt32Condition) \
345  V(CheckCacheIndicesNotCleared) \
346  V(CheckJSDataViewBounds) \
347  V(CheckTypedArrayBounds) \
348  V(CheckTypedArrayNotDetached) \
349  V(CheckMaps) \
350  V(CheckMapsWithMigrationAndDeopt) \
351  V(CheckMapsWithMigration) \
352  V(CheckMapsWithAlreadyLoadedMap) \
353  V(CheckDetectableCallable) \
354  V(CheckJSReceiverOrNullOrUndefined) \
355  V(CheckNotHole) \
356  V(CheckHoleyFloat64NotHole) \
357  V(CheckNumber) \
358  V(CheckSmi) \
359  V(CheckString) \
360  V(CheckSeqOneByteString) \
361  V(CheckStringOrStringWrapper) \
362  V(CheckStringOrOddball) \
363  V(CheckSymbol) \
364  V(CheckValue) \
365  V(CheckValueEqualsInt32) \
366  V(CheckFloat64SameValue) \
367  V(CheckValueEqualsString) \
368  V(CheckInstanceType) \
369  V(Dead) \
370  V(DebugBreak) \
371  V(FunctionEntryStackCheck) \
372  V(GeneratorStore) \
373  V(TryOnStackReplacement) \
374  V(StoreMap) \
375  V(StoreDoubleField) \
376  V(StoreFixedArrayElementWithWriteBarrier) \
377  V(StoreFixedArrayElementNoWriteBarrier) \
378  V(StoreFixedDoubleArrayElement) \
379  V(StoreInt32) \
380  V(StoreFloat64) \
381  V(StoreIntTypedArrayElement) \
382  V(StoreDoubleTypedArrayElement) \
383  V(StoreIntConstantTypedArrayElement) \
384  V(StoreDoubleConstantTypedArrayElement) \
385  V(StoreSignedIntDataViewElement) \
386  V(StoreDoubleDataViewElement) \
387  V(StoreTaggedFieldNoWriteBarrier) \
388  V(StoreTaggedFieldWithWriteBarrier) \
389  V(StoreContextSlotWithWriteBarrier) \
390  V(StoreTrustedPointerFieldWithWriteBarrier) \
391  V(HandleNoHeapWritesInterrupt) \
392  V(ReduceInterruptBudgetForLoop) \
393  V(ReduceInterruptBudgetForReturn) \
394  V(ThrowReferenceErrorIfHole) \
395  V(ThrowSuperNotCalledIfHole) \
396  V(ThrowSuperAlreadyCalledIfNotHole) \
397  V(ThrowIfNotCallable) \
398  V(ThrowIfNotSuperConstructor) \
399  V(TransitionElementsKindOrCheckMap) \
400  V(SetContinuationPreservedEmbedderData) \
401  GAP_MOVE_NODE_LIST(V) \
402  TURBOLEV_NON_VALUE_NODE_LIST(V)
403 
404 #define NODE_LIST(V) \
405  NON_VALUE_NODE_LIST(V) \
406  VALUE_NODE_LIST(V)
407 
408 #define BRANCH_CONTROL_NODE_LIST(V) \
409  V(BranchIfSmi) \
410  V(BranchIfRootConstant) \
411  V(BranchIfToBooleanTrue) \
412  V(BranchIfInt32ToBooleanTrue) \
413  V(BranchIfIntPtrToBooleanTrue) \
414  V(BranchIfFloat64ToBooleanTrue) \
415  V(BranchIfFloat64IsHole) \
416  IF_UD(V, BranchIfFloat64IsUndefinedOrHole) \
417  V(BranchIfReferenceEqual) \
418  V(BranchIfInt32Compare) \
419  V(BranchIfUint32Compare) \
420  V(BranchIfFloat64Compare) \
421  V(BranchIfUndefinedOrNull) \
422  V(BranchIfUndetectable) \
423  V(BranchIfJSReceiver) \
424  V(BranchIfTypeOf)
425 
426 #define CONDITIONAL_CONTROL_NODE_LIST(V) \
427  V(Switch) \
428  BRANCH_CONTROL_NODE_LIST(V)
429 
430 #define UNCONDITIONAL_CONTROL_NODE_LIST(V) \
431  V(Jump) \
432  V(CheckpointedJump) \
433  V(JumpLoop)
434 
435 #define TERMINAL_CONTROL_NODE_LIST(V) \
436  V(Abort) \
437  V(Return) \
438  V(Deopt)
439 
440 #define CONTROL_NODE_LIST(V) \
441  TERMINAL_CONTROL_NODE_LIST(V) \
442  CONDITIONAL_CONTROL_NODE_LIST(V) \
443  UNCONDITIONAL_CONTROL_NODE_LIST(V)
444 
445 #define NODE_BASE_LIST(V) \
446  NODE_LIST(V) \
447  CONTROL_NODE_LIST(V)
448 
449 // Define the opcode enum.
450 #define DEF_OPCODES(type) k##type,
452 #undef DEF_OPCODES
453 #define PLUS_ONE(type) +1
454 static constexpr int kOpcodeCount = NODE_BASE_LIST(PLUS_ONE);
455 static constexpr Opcode kFirstOpcode = static_cast<Opcode>(0);
456 static constexpr Opcode kLastOpcode = static_cast<Opcode>(kOpcodeCount - 1);
457 #undef PLUS_ONE
458 
459 const char* OpcodeToString(Opcode opcode);
460 inline std::ostream& operator<<(std::ostream& os, Opcode opcode) {
461  return os << OpcodeToString(opcode);
462 }
463 
464 #define V(Name) Opcode::k##Name,
465 static constexpr Opcode kFirstValueNodeOpcode =
466  std::min({VALUE_NODE_LIST(V) kLastOpcode});
467 static constexpr Opcode kLastValueNodeOpcode =
468  std::max({VALUE_NODE_LIST(V) kFirstOpcode});
471 static constexpr Opcode kLastConstantNodeOpcode =
473 static constexpr Opcode kFirstGapMoveNodeOpcode =
474  std::min({GAP_MOVE_NODE_LIST(V) kLastOpcode});
475 static constexpr Opcode kLastGapMoveNodeOpcode =
476  std::max({GAP_MOVE_NODE_LIST(V) kFirstOpcode});
477 
478 static constexpr Opcode kFirstNodeOpcode = std::min({NODE_LIST(V) kLastOpcode});
479 static constexpr Opcode kLastNodeOpcode = std::max({NODE_LIST(V) kFirstOpcode});
480 
485 
490 
495 
500 
501 static constexpr Opcode kFirstControlNodeOpcode =
502  std::min({CONTROL_NODE_LIST(V) kLastOpcode});
503 static constexpr Opcode kLastControlNodeOpcode =
504  std::max({CONTROL_NODE_LIST(V) kFirstOpcode});
505 #undef V
506 
507 constexpr bool IsValueNode(Opcode opcode) {
508  return kFirstValueNodeOpcode <= opcode && opcode <= kLastValueNodeOpcode;
509 }
510 constexpr bool IsConstantNode(Opcode opcode) {
511  return kFirstConstantNodeOpcode <= opcode &&
512  opcode <= kLastConstantNodeOpcode;
513 }
514 constexpr bool IsCommutativeNode(Opcode opcode) {
515  switch (opcode) {
516  case Opcode::kFloat64Add:
517  case Opcode::kFloat64Multiply:
518  case Opcode::kGenericStrictEqual:
519  case Opcode::kInt32AddWithOverflow:
520  case Opcode::kInt32BitwiseAnd:
521  case Opcode::kInt32BitwiseOr:
522  case Opcode::kInt32BitwiseXor:
523  case Opcode::kInt32MultiplyWithOverflow:
524  case Opcode::kStringEqual:
525  case Opcode::kTaggedEqual:
526  case Opcode::kTaggedNotEqual:
527  return true;
528  default:
529  return false;
530  }
531 }
532 constexpr bool IsZeroCostNode(Opcode opcode) {
533  switch (opcode) {
534  case Opcode::kTruncateUint32ToInt32:
535  case Opcode::kUnsafeTruncateUint32ToInt32:
536  case Opcode::kIdentity:
537  return true;
538  default:
539  return false;
540  }
541 }
542 constexpr bool IsGapMoveNode(Opcode opcode) {
543  return kFirstGapMoveNodeOpcode <= opcode && opcode <= kLastGapMoveNodeOpcode;
544 }
545 constexpr bool IsControlNode(Opcode opcode) {
546  return kFirstControlNodeOpcode <= opcode && opcode <= kLastControlNodeOpcode;
547 }
548 constexpr bool IsBranchControlNode(Opcode opcode) {
549  return kFirstBranchControlNodeOpcode <= opcode &&
551 }
552 constexpr bool IsConditionalControlNode(Opcode opcode) {
553  return kFirstConditionalControlNodeOpcode <= opcode &&
555 }
556 constexpr bool IsUnconditionalControlNode(Opcode opcode) {
557  return kFirstUnconditionalControlNodeOpcode <= opcode &&
559 }
560 constexpr bool IsTerminalControlNode(Opcode opcode) {
561  return kFirstTerminalControlNodeOpcode <= opcode &&
563 }
564 // Simple field stores are stores which do nothing but change a field value
565 // (i.e. no map transitions or calls into user code).
566 constexpr bool IsSimpleFieldStore(Opcode opcode) {
567  return opcode == Opcode::kStoreTaggedFieldWithWriteBarrier ||
568  opcode == Opcode::kStoreTaggedFieldNoWriteBarrier ||
569  opcode == Opcode::kStoreDoubleField ||
570  opcode == Opcode::kStoreFloat64 || opcode == Opcode::kStoreInt32 ||
571  opcode == Opcode::kUpdateJSArrayLength ||
572  opcode == Opcode::kStoreFixedArrayElementWithWriteBarrier ||
573  opcode == Opcode::kStoreFixedArrayElementNoWriteBarrier ||
574  opcode == Opcode::kStoreFixedDoubleArrayElement ||
575  opcode == Opcode::kStoreTrustedPointerFieldWithWriteBarrier;
576 }
577 constexpr bool IsElementsArrayWrite(Opcode opcode) {
578  return opcode == Opcode::kMaybeGrowFastElements ||
579  opcode == Opcode::kEnsureWritableFastElements;
580 }
581 constexpr bool IsTypedArrayStore(Opcode opcode) {
582  return opcode == Opcode::kStoreIntTypedArrayElement ||
583  opcode == Opcode::kStoreDoubleTypedArrayElement;
584 }
585 
586 constexpr bool CanBeStoreToNonEscapedObject(Opcode opcode) {
587  switch (opcode) {
588  case Opcode::kStoreMap:
589  case Opcode::kStoreInt32:
590  case Opcode::kStoreTrustedPointerFieldWithWriteBarrier:
591  case Opcode::kStoreTaggedFieldWithWriteBarrier:
592  case Opcode::kStoreTaggedFieldNoWriteBarrier:
593  case Opcode::kStoreContextSlotWithWriteBarrier:
594  case Opcode::kStoreFloat64:
595  return true;
596  default:
597  return false;
598  }
599 }
600 
601 // Forward-declare NodeBase sub-hierarchies.
602 class Node;
603 class ControlNode;
604 class ConditionalControlNode;
605 class BranchControlNode;
606 class UnconditionalControlNode;
607 class TerminalControlNode;
608 class ValueNode;
609 
610 enum class ValueRepresentation : uint8_t {
611  kTagged,
612  kInt32,
613  kUint32,
614  kFloat64,
616  kIntPtr
617 };
618 
619 inline constexpr bool IsDoubleRepresentation(ValueRepresentation repr) {
620  return repr == ValueRepresentation::kFloat64 ||
622 }
623 
625 #if defined(V8_TARGET_ARCH_RISCV64)
626  // on RISC-V int32 are always sign-extended
627  return false;
628 #else
629  return (repr == ValueRepresentation::kUint32 ||
631 #endif
632 }
633 
634 // TODO(olivf): Rename Unknown to Any.
635 
636 /* Every object should belong to exactly one of these.*/
637 #define LEAF_NODE_TYPE_LIST(V) \
638  V(Smi, (1 << 0)) \
639  V(HeapNumber, (1 << 1)) \
640  V(Null, (1 << 2)) \
641  V(Undefined, (1 << 3)) \
642  V(Boolean, (1 << 4)) \
643  V(Symbol, (1 << 5)) \
644  /* String Venn diagram: */ \
645  /* ┌String───────────────────────────────────┐ */ \
646  /* │ OtherString │ */ \
647  /* │┌InternalizedString───┐ │ */ \
648  /* ││ │ │ */ \
649  /* ││OtherInternalized │ │ */ \
650  /* ││String │ │ */ \
651  /* │├─────────────────────┼─SeqOneByteString┐│ */ \
652  /* ││ │ ││ */ \
653  /* ││OtherSeqInternalized │ OtherSeqOneByte ││ */ \
654  /* ││OneByteString │ String ││ */ \
655  /* │├──────────────────┐ │ ││ */ \
656  /* ││ROSeqInternalized │ │ ││ */ \
657  /* ││OneByteString │ │ ││ */ \
658  /* │└──────────────────┴──┴─────────────────┘│ */ \
659  /* └─────────────────────────────────────────┘ */ \
660  V(ROSeqInternalizedOneByteString, (1 << 6)) \
661  V(OtherSeqInternalizedOneByteString, (1 << 7)) \
662  V(OtherInternalizedString, (1 << 8)) \
663  V(OtherSeqOneByteString, (1 << 9)) \
664  V(OtherString, (1 << 10)) \
665  \
666  V(Context, (1 << 11)) \
667  V(StringWrapper, (1 << 12)) \
668  V(JSArray, (1 << 13)) \
669  V(JSFunction, (1 << 14)) \
670  V(OtherCallable, (1 << 15)) \
671  V(OtherHeapObject, (1 << 16)) \
672  V(OtherJSReceiver, (1 << 17))
673 
674 #define COUNT(...) +1
676 #undef COUNT
677 
678 #define COMBINED_NODE_TYPE_LIST(V) \
679  /* A value which has all the above bits set */ \
680  V(Unknown, ((1 << kNumberOfLeafNodeTypes) - 1)) \
681  V(Callable, kJSFunction | kOtherCallable) \
682  V(NullOrUndefined, kNull | kUndefined) \
683  V(Oddball, kNullOrUndefined | kBoolean) \
684  V(Number, kSmi | kHeapNumber) \
685  V(NumberOrBoolean, kNumber | kBoolean) \
686  V(NumberOrOddball, kNumber | kOddball) \
687  V(InternalizedString, kROSeqInternalizedOneByteString | \
688  kOtherSeqInternalizedOneByteString | \
689  kOtherInternalizedString) \
690  V(SeqOneByteString, kROSeqInternalizedOneByteString | \
691  kOtherSeqInternalizedOneByteString | \
692  kOtherSeqOneByteString) \
693  V(String, kInternalizedString | kSeqOneByteString | kOtherString) \
694  V(StringOrStringWrapper, kString | kStringWrapper) \
695  V(StringOrOddball, kString | kOddball) \
696  V(Name, kString | kSymbol) \
697  V(JSReceiver, kJSArray | kCallable | kStringWrapper | kOtherJSReceiver) \
698  V(JSReceiverOrNullOrUndefined, kJSReceiver | kNullOrUndefined) \
699  V(AnyHeapObject, kUnknown - kSmi)
700 
701 #define NODE_TYPE_LIST(V) \
702  LEAF_NODE_TYPE_LIST(V) \
703  COMBINED_NODE_TYPE_LIST(V)
704 
705 enum class NodeType : uint32_t {
706 #define DEFINE_NODE_TYPE(Name, Value) k##Name = Value,
708 #undef DEFINE_NODE_TYPE
709 };
710 using NodeTypeInt = std::underlying_type_t<NodeType>;
711 
712 // Some leaf node types only exist to complement other leaf node types in a
713 // combined type. We never expect to see these as standalone types.
714 inline constexpr bool NodeTypeIsNeverStandalone(NodeType type) {
715  switch (type) {
716  // "Other" string types should be considered internal and never appear as
717  // standalone leaf types.
718  case NodeType::kOtherCallable:
719  case NodeType::kOtherInternalizedString:
720  case NodeType::kOtherSeqInternalizedOneByteString:
721  case NodeType::kOtherSeqOneByteString:
722  case NodeType::kOtherString:
723  return true;
724  default:
725  return false;
726  }
727 }
728 
729 inline constexpr NodeType EmptyNodeType() { return static_cast<NodeType>(0); }
730 
731 inline constexpr NodeType IntersectType(NodeType left, NodeType right) {
734  return static_cast<NodeType>(static_cast<NodeTypeInt>(left) &
735  static_cast<NodeTypeInt>(right));
736 }
737 inline constexpr NodeType UnionType(NodeType left, NodeType right) {
740  return static_cast<NodeType>(static_cast<NodeTypeInt>(left) |
741  static_cast<NodeTypeInt>(right));
742 }
743 inline constexpr bool NodeTypeIs(NodeType type, NodeType to_check) {
745  DCHECK(!NodeTypeIsNeverStandalone(to_check));
746  NodeTypeInt right = static_cast<NodeTypeInt>(to_check);
747  return (static_cast<NodeTypeInt>(type) & (~right)) == 0;
748 }
749 inline constexpr bool NodeTypeCanBe(NodeType type, NodeType to_check) {
751  DCHECK(!NodeTypeIsNeverStandalone(to_check));
752  NodeTypeInt right = static_cast<NodeTypeInt>(to_check);
753  return (static_cast<NodeTypeInt>(type) & (right)) != 0;
754 }
755 
756 inline constexpr bool NodeTypeIsUnstable(NodeType type) {
758  // Any type that can be a string might be unstable, if the string part of the
759  // type is unstable.
760  if (NodeTypeCanBe(type, NodeType::kString)) {
761  // Extract out the string part of the node type.
762  NodeType string_type = IntersectType(type, NodeType::kString);
763  // RO-space strings are ok, since they can't change.
764  if (string_type == NodeType::kROSeqInternalizedOneByteString) return false;
765  // The generic internalized string type is ok, since it doesn't consider
766  // seqness and internalized strings stay internalized.
767  if (string_type == NodeType::kInternalizedString) return false;
768  // The generic string type is ok, since it defines all strings.
769  if (string_type == NodeType::kString) return false;
770  // Otherwise, a string can get in-place externalized, or in-place converted
771  // to thin if not already internalized, both of which lose seq-ness.
772  // TODO(leszeks): We could probably consider byteness of internalized
773  // strings to be stable, since we can't change byteness with in-place
774  // externalization.
775  return true;
776  }
777  // All other node types are stable.
778  return false;
779 }
780 // Seq strings are unstable because they could be in-place converted to thin
781 // strings.
782 static_assert(NodeTypeIsUnstable(NodeType::kSeqOneByteString));
783 // Internalized strings are stable because they have to stay internalized.
784 static_assert(!NodeTypeIsUnstable(NodeType::kInternalizedString));
785 // RO internalized strings are stable because they are read-only.
786 static_assert(!NodeTypeIsUnstable(NodeType::kROSeqInternalizedOneByteString));
787 // The generic string type is stable because we've already erased any
788 // information about it.
789 static_assert(!NodeTypeIsUnstable(NodeType::kString));
790 // A type which contains an unstable string should also be unstable.
791 static_assert(NodeTypeIsUnstable(UnionType(NodeType::kNumber,
792  NodeType::kSeqOneByteString)));
793 // A type which contains a stable string should also be stable.
794 static_assert(!NodeTypeIsUnstable(UnionType(NodeType::kNumber,
795  NodeType::kInternalizedString)));
796 
799  if (!NodeTypeIsUnstable(type)) return type;
800  // Strings can be in-place internalized, turned into thin strings, and
801  // in-place externalized, and byteness can change from one->two byte (because
802  // of internalized external strings with two-byte encoding of one-byte data)
803  // or two->one byte (because of internalizing a two-byte slice with one-byte
804  // data). The only invariant that we can preserve is that internalized strings
805  // stay internalized.
806  DCHECK(NodeTypeCanBe(type, NodeType::kString));
807  // Extract out the string part of the node type.
808  NodeType string_type = IntersectType(type, NodeType::kString);
809  if (NodeTypeIs(string_type, NodeType::kInternalizedString)) {
810  // Strings that can't be anything but internalized become generic
811  // internalized.
812  type = UnionType(type, NodeType::kInternalizedString);
813  } else {
814  // All other strings become fully generic.
815  type = UnionType(type, NodeType::kString);
816  }
818  return type;
819 }
820 // Seq strings become normal strings with unspecified byteness when made stable,
821 // because they could have been internalized into a two-byte external string.
822 static_assert(MakeTypeStable(NodeType::kSeqOneByteString) == NodeType::kString);
823 // Generic internalized strings stay as they are.
824 static_assert(MakeTypeStable(NodeType::kInternalizedString) ==
825  NodeType::kInternalizedString);
826 // Read-only seq internalized strings become generic.
827 static_assert(MakeTypeStable(NodeType::kROSeqInternalizedOneByteString) ==
828  NodeType::kROSeqInternalizedOneByteString);
829 // Stabilizing a type which is partially an unstable string should generalize
830 // the string part of the type
831 static_assert(MakeTypeStable(UnionType(NodeType::kNumber,
832  NodeType::kSeqOneByteString)) ==
833  UnionType(NodeType::kNumber, NodeType::kString));
834 
835 // Assert that the Unknown type is constructed correctly.
836 #define ADD_STATIC_ASSERT(Name, Value) \
837  static_assert(NodeTypeIsNeverStandalone(NodeType::k##Name) || \
838  NodeTypeIs(NodeType::k##Name, NodeType::kUnknown));
840 #undef ADD_STATIC_ASSERT
841 
844  if (map.IsHeapNumberMap()) return NodeType::kHeapNumber;
845  if (map.IsStringMap()) {
846  if (map.IsInternalizedStringMap()) {
847  return NodeType::kInternalizedString;
848  }
849  if (map.IsSeqStringMap() && map.IsOneByteStringMap()) {
850  return NodeType::kSeqOneByteString;
851  }
852  return NodeType::kString;
853  }
854  if (map.IsStringWrapperMap()) return NodeType::kStringWrapper;
855  if (map.IsSymbolMap()) return NodeType::kSymbol;
856  if (map.IsBooleanMap(broker)) return NodeType::kBoolean;
857  if (map.IsOddballMap()) {
858  // Oddball but not a Boolean.
859  return NodeType::kNullOrUndefined;
860  }
861  if (map.IsContextMap()) return NodeType::kContext;
862  if (map.IsJSArrayMap()) return NodeType::kJSArray;
863  if (map.IsJSFunctionMap()) return NodeType::kJSFunction;
864  if (map.is_callable()) {
865  return NodeType::kCallable;
866  }
867  if (map.IsJSReceiverMap()) {
868  // JSReceiver but not any of the above.
869  return NodeType::kOtherJSReceiver;
870  }
871  return NodeType::kOtherHeapObject;
872 }
873 
874 inline constexpr bool IsEmptyNodeType(NodeType type) {
875  // No bits are set.
876  return static_cast<int>(type) == 0;
877 }
878 
880  compiler::ObjectRef ref) {
881  if (ref.IsSmi()) return NodeType::kSmi;
882  NodeType type = StaticTypeForMap(ref.AsHeapObject().map(broker), broker);
884  if (type == NodeType::kInternalizedString && ref.is_read_only()) {
885  if (ref.AsString().IsSeqString() &&
886  ref.AsString().IsOneByteRepresentation()) {
887  type = NodeType::kROSeqInternalizedOneByteString;
888  }
889  }
890  return type;
891 }
892 
895  switch (type) {
896  case NodeType::kSmi:
897  return false;
898  case NodeType::kHeapNumber:
899  return map.IsHeapNumberMap();
900  case NodeType::kNull:
901  return map.IsNullMap(broker);
902  case NodeType::kUndefined:
903  return map.IsUndefinedMap(broker);
904  case NodeType::kBoolean:
905  return map.IsBooleanMap(broker);
906  case NodeType::kSymbol:
907  return map.IsSymbolMap();
908  case NodeType::kOtherString:
909  // This doesn't exclude other string leaf types, which means one should
910  // never test for this node type alone.
911  return map.IsStringMap();
912  case NodeType::kOtherSeqOneByteString:
913  return map.IsSeqStringMap() && map.IsOneByteStringMap();
914  // We can't prove with a map alone that an object is in RO-space, but
915  // these maps will be potential candidates.
916  case NodeType::kROSeqInternalizedOneByteString:
917  case NodeType::kOtherSeqInternalizedOneByteString:
918  return map.IsInternalizedStringMap() && map.IsSeqStringMap() &&
919  map.IsOneByteStringMap();
920  case NodeType::kOtherInternalizedString:
921  return map.IsInternalizedStringMap();
922  case NodeType::kStringWrapper:
923  return map.IsStringWrapperMap();
924  case NodeType::kContext:
925  return map.IsContextMap();
926  case NodeType::kJSArray:
927  return map.IsJSArrayMap();
928  case NodeType::kJSFunction:
929  return map.IsJSFunctionMap();
930  case NodeType::kCallable:
931  return map.is_callable();
932  case NodeType::kOtherCallable:
933  return map.is_callable() && !map.IsJSFunctionMap();
934  case NodeType::kOtherJSReceiver:
935  return map.IsJSReceiverMap() && !map.IsJSArrayMap() &&
936  !map.is_callable() && !map.IsStringWrapperMap();
937  case NodeType::kOtherHeapObject:
938  return !map.IsHeapNumberMap() && !map.IsOddballMap() &&
939  !map.IsContextMap() && !map.IsSymbolMap() && !map.IsStringMap() &&
940  !map.IsJSReceiverMap();
941  default:
942  UNREACHABLE();
943  }
944 }
945 
949 
950  // Early return for any heap object.
951  if (NodeTypeIs(NodeType::kAnyHeapObject, type)) {
952  // Unknown types will be handled here too.
953  static_assert(NodeTypeIs(NodeType::kAnyHeapObject, NodeType::kUnknown));
954  return true;
955  }
956 
957  // Iterate over each leaf type bit in the type bitmask, and check if the map
958  // matches it.
959  NodeTypeInt type_bits = static_cast<NodeTypeInt>(type);
960  while (type_bits != 0) {
961  NodeTypeInt current_bit =
963  NodeType leaf_type = static_cast<NodeType>(current_bit);
964  if (IsInstanceOfLeafNodeType(map, leaf_type, broker)) return true;
965  type_bits = base::bits::ClearLsb(type_bits);
966  }
967  return false;
968 }
969 
970 inline std::ostream& operator<<(std::ostream& out, const NodeType& type) {
971  if (IsEmptyNodeType(type)) {
972  out << "Empty";
973  return out;
974  }
975  switch (type) {
976 #define CASE(Name, _) \
977  case NodeType::k##Name: \
978  out << #Name; \
979  break;
981 #undef CASE
982  default:
983 #define CASE(Name, _) \
984  if (NodeTypeIs(NodeType::k##Name, type)) { \
985  if constexpr (NodeType::k##Name != NodeType::kUnknown) { \
986  out << #Name "|"; \
987  } \
988  }
990 #undef CASE
991  }
992  return out;
993 }
994 
995 #define DEFINE_NODE_TYPE_CHECK(Type, _) \
996  inline bool NodeTypeIs##Type(NodeType type) { \
997  return NodeTypeIs(type, NodeType::k##Type); \
998  }
1000 #undef DEFINE_NODE_TYPE_CHECK
1001 
1003  return (static_cast<int>(type) &
1004  static_cast<int>(NodeType::kNullOrUndefined)) != 0;
1005 }
1006 
1007 enum class TaggedToFloat64ConversionType : uint8_t {
1008  kOnlyNumber,
1011 };
1012 
1013 constexpr Condition ConditionFor(Operation cond);
1014 constexpr Condition ConditionForNaN();
1015 
1016 bool FromConstantToBool(LocalIsolate* local_isolate, ValueNode* node);
1018 
1019 inline std::ostream& operator<<(std::ostream& os,
1020  const ValueRepresentation& repr) {
1021  switch (repr) {
1023  return os << "Tagged";
1025  return os << "Int32";
1027  return os << "Uint32";
1029  return os << "Float64";
1031  return os << "HoleyFloat64";
1033  return os << "Word64";
1034  }
1035 }
1036 
1037 inline std::ostream& operator<<(
1038  std::ostream& os, const TaggedToFloat64ConversionType& conversion_type) {
1039  switch (conversion_type) {
1041  return os << "Number";
1043  return os << "NumberOrBoolean";
1045  return os << "NumberOrOddball";
1046  }
1047 }
1048 
1050  for (compiler::MapRef map : maps) {
1051  if (!map.IsJSTypedArrayMap()) return false;
1052  }
1053  return true;
1054 }
1055 
1057  for (compiler::MapRef map : maps) {
1058  if (!map.IsJSArrayMap()) return false;
1059  }
1060  return true;
1061 }
1062 
1064  for (compiler::MapRef map : maps) {
1065  if (!map.IsJSObjectMap()) return false;
1066  }
1067  return true;
1068 }
1069 
1071  for (compiler::MapRef map : maps) {
1072  if (!map.IsStringMap()) return false;
1073  }
1074  return true;
1075 }
1076 
1078  for (compiler::MapRef map : maps) {
1079  if (map.instance_type() != HEAP_NUMBER_TYPE) return false;
1080  }
1081  return true;
1082 }
1083 
1085  for (compiler::MapRef map : maps) {
1086  if (map.instance_type() == HEAP_NUMBER_TYPE) return true;
1087  }
1088  return false;
1089 }
1090 
1091 #define DEF_FORWARD_DECLARATION(type, ...) class type;
1093 #undef DEF_FORWARD_DECLARATION
1094 
1095 using NodeIdT = uint32_t;
1096 static constexpr NodeIdT kInvalidNodeId = 0;
1097 static constexpr NodeIdT kFirstValidNodeId = 1;
1098 
1099 // Represents either a direct BasicBlock pointer, or an entry in a list of
1100 // unresolved BasicBlockRefs which will be mutated (in place) at some point into
1101 // direct BasicBlock pointers.
1103  struct BasicBlockRefBuilder;
1104 
1105  public:
1107 #ifdef DEBUG
1108  state_ = kRefList;
1109 #endif
1110  }
1111  explicit BasicBlockRef(BasicBlock* block) : block_ptr_(block) {
1112 #ifdef DEBUG
1113  state_ = kBlockPointer;
1114 #endif
1115  }
1116 
1117  // Refs can't be copied or moved, since they are referenced by `this` pointer
1118  // in the ref list.
1119  BasicBlockRef(const BasicBlockRef&) = delete;
1123 
1124  // Construct a new ref-list mode BasicBlockRef and add it to the given ref
1125  // list.
1126  explicit BasicBlockRef(BasicBlockRef* ref_list_head) : BasicBlockRef() {
1127  BasicBlockRef* old_next_ptr = MoveToRefList(ref_list_head);
1128  USE(old_next_ptr);
1129  DCHECK_NULL(old_next_ptr);
1130  }
1131 
1132  // Change this ref to a direct basic block pointer, returning the old "next"
1133  // pointer of the current ref.
1135  DCHECK_EQ(state_, kRefList);
1136 
1137  BasicBlockRef* old_next_ptr = next_ref_;
1138  block_ptr_ = block;
1139 #ifdef DEBUG
1140  state_ = kBlockPointer;
1141 #endif
1142  return old_next_ptr;
1143  }
1144 
1145  // Reset this ref list to null, returning the old ref list (i.e. the old
1146  // "next" pointer).
1148  DCHECK_EQ(state_, kRefList);
1149 
1150  BasicBlockRef* old_next_ptr = next_ref_;
1151  next_ref_ = nullptr;
1152  return old_next_ptr;
1153  }
1154 
1155  // Move this ref to the given ref list, returning the old "next" pointer of
1156  // the current ref.
1158  DCHECK_EQ(state_, kRefList);
1159  DCHECK_EQ(ref_list_head->state_, kRefList);
1160 
1161  BasicBlockRef* old_next_ptr = next_ref_;
1162  next_ref_ = ref_list_head->next_ref_;
1163  ref_list_head->next_ref_ = this;
1164  return old_next_ptr;
1165  }
1166 
1167  void Bind(BasicBlock* block) {
1168  DCHECK_EQ(state_, kRefList);
1169 
1171  while (next_ref != nullptr) {
1173  }
1174  DCHECK_EQ(block_ptr(), block);
1175  }
1176 
1178  DCHECK_EQ(state_, kBlockPointer);
1179  return block_ptr_;
1180  }
1181 
1182  void set_block_ptr(BasicBlock* block) {
1183  DCHECK_EQ(state_, kBlockPointer);
1184  block_ptr_ = block;
1185  }
1186 
1188  DCHECK_EQ(state_, kRefList);
1189  return next_ref_;
1190  }
1191 
1192  bool has_ref() const {
1193  DCHECK_EQ(state_, kRefList);
1194  return next_ref_ != nullptr;
1195  }
1196 
1197  private:
1198  union {
1201  };
1202 #ifdef DEBUG
1203  enum { kBlockPointer, kRefList } state_;
1204 #endif // DEBUG
1205 };
1206 
1208  public:
1209  constexpr bool is_call() const {
1210  // Only returns true for non-deferred calls. Use `is_any_call` to check
1211  // deferred calls as well.
1212  return kIsCallBit::decode(bitfield_);
1213  }
1214  constexpr bool is_any_call() const { return is_call() || is_deferred_call(); }
1215  constexpr bool can_eager_deopt() const {
1218  }
1219  constexpr bool can_lazy_deopt() const {
1222  }
1223  constexpr bool is_deopt_checkpoint() const {
1226  }
1227  constexpr bool can_deopt() const {
1228  return can_eager_deopt() || can_lazy_deopt();
1229  }
1230  constexpr bool can_throw() const {
1232  }
1233  // TODO(olivf) We should negate all of these properties which would give them
1234  // a less error-prone default state.
1235  constexpr bool can_read() const { return kCanReadBit::decode(bitfield_); }
1236  constexpr bool can_write() const { return kCanWriteBit::decode(bitfield_); }
1237  constexpr bool can_allocate() const {
1239  }
1240  // Only for ValueNodes, indicates that the instruction might return something
1241  // new every time it is executed. For example it creates an object that is
1242  // unique with regards to strict equality comparison or it reads a value that
1243  // can change in absence of an explicit write instruction.
1244  constexpr bool not_idempotent() const {
1246  }
1249  }
1250  constexpr bool is_tagged() const {
1252  }
1253  constexpr bool is_conversion() const {
1255  }
1256  constexpr bool needs_register_snapshot() const {
1258  }
1259  constexpr bool is_pure() const {
1260  return (bitfield_ & kPureMask) == kPureValue;
1261  }
1262  constexpr bool is_required_when_unused() const {
1263  if (is_conversion()) {
1264  // Calls in conversions are not counted as a side-effect as far as
1265  // is_required_when_unused is concerned, since they should always be to
1266  // the Allocate builtin.
1267  return can_write() || can_throw() || can_deopt();
1268  } else {
1269  return can_write() || can_throw() || can_deopt() || is_any_call();
1270  }
1271  }
1272  constexpr bool can_participate_in_cse() const {
1273  return !can_write() && !not_idempotent();
1274  }
1275 
1276  constexpr OpProperties operator|(const OpProperties& that) {
1277  return OpProperties(bitfield_ | that.bitfield_);
1278  }
1279 
1280  static constexpr OpProperties Pure() { return OpProperties(kPureValue); }
1281  static constexpr OpProperties Call() {
1282  return OpProperties(kIsCallBit::encode(true));
1283  }
1284  static constexpr OpProperties EagerDeopt() {
1285  return OpProperties(
1287  }
1288  static constexpr OpProperties LazyDeopt() {
1289  return OpProperties(
1291  }
1292  static constexpr OpProperties DeoptCheckpoint() {
1293  return OpProperties(
1295  }
1296  static constexpr OpProperties CanThrow() {
1297  return OpProperties(kCanThrowBit::encode(true)) | LazyDeopt() |
1298  CanAllocate();
1299  }
1300  static constexpr OpProperties CanRead() {
1301  return OpProperties(kCanReadBit::encode(true));
1302  }
1303  static constexpr OpProperties CanWrite() {
1304  return OpProperties(kCanWriteBit::encode(true));
1305  }
1306  static constexpr OpProperties CanAllocate() {
1307  return OpProperties(kCanAllocateBit::encode(true));
1308  }
1309  static constexpr OpProperties NotIdempotent() {
1311  }
1312  static constexpr OpProperties TaggedValue() {
1313  return OpProperties(
1315  }
1316  static constexpr OpProperties ExternalReference() {
1317  return OpProperties(
1319  }
1320  static constexpr OpProperties Int32() {
1321  return OpProperties(
1323  }
1324  static constexpr OpProperties Uint32() {
1325  return OpProperties(
1327  }
1328  static constexpr OpProperties Float64() {
1329  return OpProperties(
1331  }
1332  static constexpr OpProperties HoleyFloat64() {
1333  return OpProperties(
1335  }
1336  static constexpr OpProperties IntPtr() {
1337  return OpProperties(
1339  }
1340  static constexpr OpProperties TrustedPointer() {
1341  return OpProperties(
1343  }
1345  ValueRepresentation repr) {
1347  }
1348  static constexpr OpProperties ConversionNode() {
1349  return OpProperties(kIsConversionBit::encode(true));
1350  }
1351  static constexpr OpProperties CanCallUserCode() {
1352  return AnySideEffects() | LazyDeopt() | CanThrow();
1353  }
1354  // Without auditing the call target, we must assume it can cause a lazy deopt
1355  // and throw. Use this when codegen calls runtime or a builtin, unless
1356  // certain that the target either doesn't throw or cannot deopt.
1357  // TODO(jgruber): Go through all nodes marked with this property and decide
1358  // whether to keep it (or remove either the lazy-deopt or throw flag).
1360  return Call() | CanCallUserCode() | NotIdempotent();
1361  }
1362  static constexpr OpProperties JSCall() { return Call() | CanCallUserCode(); }
1363  static constexpr OpProperties AnySideEffects() {
1364  return CanRead() | CanWrite() | CanAllocate();
1365  }
1366  static constexpr OpProperties DeferredCall() {
1367  // Operations with a deferred call need a snapshot of register state,
1368  // because they need to be able to push registers to save them, and annotate
1369  // the safepoint with information about which registers are tagged.
1370  return NeedsRegisterSnapshot();
1371  }
1372 
1373  constexpr explicit OpProperties(uint32_t bitfield) : bitfield_(bitfield) {}
1374  operator uint32_t() const { return bitfield_; }
1375 
1378  }
1379 
1381  return OpProperties(
1383  }
1384 
1385  private:
1398 
1399  static const uint32_t kPureMask =
1401  static const uint32_t kPureValue = kCanReadBit::encode(false) |
1402  kCanWriteBit::encode(false) |
1403  kCanAllocateBit::encode(false);
1404 
1405  // NeedsRegisterSnapshot is only used for DeferredCall, and we rely on this in
1406  // `is_deferred_call` to detect deferred calls. If you need to use
1407  // NeedsRegisterSnapshot for something else that DeferredCalls, then you'll
1408  // have to update `is_any_call`.
1411  }
1412 
1413  const uint32_t bitfield_;
1414 
1415  public:
1417 
1418  constexpr bool is_deferred_call() const {
1419  // Currently, there is no kDeferredCall bit, but DeferredCall only sets a
1420  // single bit: kNeedsRegisterSnapShot. If this static assert breaks, it
1421  // means that you added additional properties to DeferredCall, and you
1422  // should update this function accordingly.
1423  static_assert(DeferredCall().bitfield_ ==
1425  return needs_register_snapshot();
1426  }
1427 };
1428 
1429 constexpr inline OpProperties StaticPropertiesForOpcode(Opcode opcode);
1430 
1432  public:
1433  ValueLocation() = default;
1434 
1435  template <typename... Args>
1436  void SetUnallocated(Args&&... args) {
1437  DCHECK(operand_.IsInvalid());
1439  }
1440 
1441  template <typename... Args>
1442  void SetAllocated(Args&&... args) {
1443  DCHECK(operand_.IsUnallocated());
1445  }
1446 
1447  // Only to be used on inputs that inherit allocation.
1449  operand_ = location;
1450  }
1451 
1452  // We use USED_AT_START to indicate that the input will be clobbered.
1453  bool Cloberred() {
1454  DCHECK(operand_.IsUnallocated());
1455  return compiler::UnallocatedOperand::cast(operand_).IsUsedAtStart();
1456  }
1457 
1458  template <typename... Args>
1459  void SetConstant(Args&&... args) {
1460  DCHECK(operand_.IsUnallocated());
1462  }
1463 
1467  }
1468 
1472  }
1473 
1474  bool IsAnyRegister() const { return operand_.IsAnyRegister(); }
1475  bool IsGeneralRegister() const { return operand_.IsRegister(); }
1476  bool IsDoubleRegister() const { return operand_.IsDoubleRegister(); }
1477 
1478  const compiler::InstructionOperand& operand() const { return operand_; }
1480 
1481  private:
1483 };
1484 
1486  public:
1487  NodeIdT next_use_id() const { return next_use_id_; }
1488  // Used in ValueNode::mark_use
1490 
1491  private:
1493 };
1494 
1495 class Input : public InputLocation {
1496  public:
1497  explicit Input(ValueNode* node) : node_(node) {}
1498  ValueNode* node() const { return node_; }
1500  void clear();
1501 
1502  private:
1504 };
1505 
1506 class VirtualObjectList;
1507 class InterpretedDeoptFrame;
1511 class DeoptFrame {
1512  public:
1513  enum class FrameType {
1518  };
1519 
1526  };
1527 
1533  };
1534 
1540  };
1541 
1546  compiler::OptionalJSFunctionRef maybe_js_target;
1547  };
1548 
1552 
1554  : data_(std::move(data)), parent_(parent) {}
1555 
1557  : data_(data), parent_(parent) {}
1558 
1559  FrameType type() const { return data_.tag(); }
1560  DeoptFrame* parent() { return parent_; }
1561  const DeoptFrame* parent() const { return parent_; }
1562 
1563  inline const InterpretedDeoptFrame& as_interpreted() const;
1564  inline const InlinedArgumentsDeoptFrame& as_inlined_arguments() const;
1565  inline const ConstructInvokeStubDeoptFrame& as_construct_stub() const;
1571  inline bool IsJsFrame() const;
1572 
1573  inline const MaglevCompilationUnit& GetCompilationUnit() const;
1574  inline BytecodeOffset GetBytecodeOffset() const;
1575  inline SourcePosition GetSourcePosition() const;
1578  inline VirtualObjectList GetVirtualObjects() const;
1579 
1580  protected:
1582  : data_(std::move(data)), parent_(parent) {}
1584  : data_(std::move(data)), parent_(parent) {}
1586  : data_(std::move(data)), parent_(parent) {}
1588  : data_(std::move(data)), parent_(parent) {}
1589 
1592 };
1593 
1595  public:
1602  parent) {}
1603 
1604  const MaglevCompilationUnit& unit() const { return data().unit; }
1606  return data().frame_state;
1607  }
1608  ValueNode*& closure() { return data().closure; }
1609  ValueNode* closure() const { return data().closure; }
1612 
1613  int ComputeReturnOffset(interpreter::Register result_location,
1614  int result_size) const;
1615 
1616  private:
1618  const InterpretedFrameData& data() const {
1619  return data_.get<InterpretedFrameData>();
1620  }
1621 };
1622 
1623 // Make sure storing/passing deopt frames by value doesn't truncate them.
1624 static_assert(sizeof(InterpretedDeoptFrame) == sizeof(DeoptFrame));
1625 
1628  return static_cast<const InterpretedDeoptFrame&>(*this);
1629 }
1632  return static_cast<InterpretedDeoptFrame&>(*this);
1633 }
1634 
1636  public:
1639  ValueNode* closure,
1641  DeoptFrame* parent)
1643  arguments},
1644  parent) {}
1645 
1646  const MaglevCompilationUnit& unit() const { return data().unit; }
1648  ValueNode*& closure() { return data().closure; }
1649  ValueNode* closure() const { return data().closure; }
1651 
1652  private:
1655  }
1658  }
1659 };
1660 
1661 // Make sure storing/passing deopt frames by value doesn't truncate them.
1662 static_assert(sizeof(InlinedArgumentsDeoptFrame) == sizeof(DeoptFrame));
1663 
1665  const {
1667  return static_cast<const InlinedArgumentsDeoptFrame&>(*this);
1668 }
1671  return static_cast<InlinedArgumentsDeoptFrame&>(*this);
1672 }
1673 
1675  public:
1679  DeoptFrame* parent)
1681  context},
1682  parent) {}
1683 
1684  const MaglevCompilationUnit& unit() const { return data().unit; }
1685  ValueNode*& receiver() { return data().receiver; }
1686  ValueNode* receiver() const { return data().receiver; }
1687  ValueNode*& context() { return data().context; }
1688  ValueNode* context() const { return data().context; }
1690 
1691  private:
1694  }
1697  }
1698 };
1699 
1700 // Make sure storing/passing deopt frames by value doesn't truncate them.
1701 static_assert(sizeof(ConstructInvokeStubDeoptFrame) == sizeof(DeoptFrame));
1702 
1704  const {
1706  return static_cast<const ConstructInvokeStubDeoptFrame&>(*this);
1707 }
1708 
1711  return static_cast<ConstructInvokeStubDeoptFrame&>(*this);
1712 }
1713 
1715  public:
1718  ValueNode* context,
1719  compiler::OptionalJSFunctionRef maybe_js_target,
1720  DeoptFrame* parent)
1722  maybe_js_target},
1723  parent) {}
1724 
1725  const Builtin& builtin_id() const { return data().builtin_id; }
1727  ValueNode*& context() { return data().context; }
1728  ValueNode* context() const { return data().context; }
1729  bool is_javascript() const { return data().maybe_js_target.has_value(); }
1731  return data().maybe_js_target.value();
1732  }
1733 
1734  private:
1737  }
1740  }
1741 };
1742 
1743 // Make sure storing/passing deopt frames by value doesn't truncate them.
1744 static_assert(sizeof(BuiltinContinuationDeoptFrame) == sizeof(DeoptFrame));
1745 
1746 inline const BuiltinContinuationDeoptFrame&
1749  return static_cast<const BuiltinContinuationDeoptFrame&>(*this);
1750 }
1753  return static_cast<BuiltinContinuationDeoptFrame&>(*this);
1754 }
1755 
1756 inline bool DeoptFrame::IsJsFrame() const {
1757  // This must be in sync with TRANSLATION_JS_FRAME_OPCODE_LIST in
1758  // translation-opcode.h or bad things happen.
1759  switch (data_.tag()) {
1761  return true;
1766  return false;
1767  }
1768 }
1769 
1771  switch (type()) {
1773  return as_interpreted().unit();
1775  return as_inlined_arguments().unit();
1777  return as_construct_stub().unit();
1779  return parent()->GetCompilationUnit();
1780  }
1781 }
1782 
1784  switch (type()) {
1786  return as_interpreted().bytecode_position();
1789  return parent()->GetBytecodeOffset();
1791  return BytecodeOffset::None();
1794  as_builtin_continuation().builtin_id());
1795  }
1796 }
1797 
1799  switch (type()) {
1801  return as_interpreted().source_position();
1804  return parent()->GetSourcePosition();
1809  return parent()->GetSourcePosition();
1810  }
1811 }
1812 
1814  const {
1816 }
1817 
1819  return GetCompilationUnit().bytecode();
1820 }
1821 
1822 class DeoptInfo {
1823  protected:
1824  DeoptInfo(Zone* zone, const DeoptFrame top_frame,
1826 
1827  public:
1829  const DeoptFrame& top_frame() const { return top_frame_; }
1831  return feedback_to_update_;
1832  }
1833 
1834  bool has_input_locations() const { return input_locations_ != nullptr; }
1837  return input_locations_;
1838  }
1839  void InitializeInputLocations(Zone* zone, size_t count);
1840 
1842 
1843  int translation_index() const { return translation_index_; }
1845 
1846 #ifdef DEBUG
1847  size_t input_location_count() { return input_location_count_; }
1848 #endif // DEBUG
1849 
1850  private:
1854 #ifdef DEBUG
1855  size_t input_location_count_ = 0;
1856 #endif // DEBUG
1859 };
1860 
1865 };
1866 
1867 class EagerDeoptInfo : public DeoptInfo {
1868  public:
1872 
1873  DeoptimizeReason reason() const { return reason_; }
1875 
1876  template <typename Function>
1877  void ForEachInput(Function&& f);
1878  template <typename Function>
1879  void ForEachInput(Function&& f) const;
1880 
1881  private:
1882  DeoptimizeReason reason_ = DeoptimizeReason::kUnknown;
1883 };
1884 
1885 class LazyDeoptInfo : public DeoptInfo {
1886  public:
1892  bitfield_(
1894  ResultSizeField::encode(result_size)) {}
1895 
1897  DCHECK(IsConsideredForResultLocation());
1898  return result_location_;
1899  }
1900  int result_size() const {
1901  DCHECK(IsConsideredForResultLocation());
1903  }
1904 
1905  bool IsResultRegister(interpreter::Register reg) const;
1906  bool HasResultLocation() const {
1907  DCHECK(IsConsideredForResultLocation());
1908  return result_location_.is_valid();
1909  }
1910 
1912  const ExceptionHandlerInfo* handler_info);
1913 
1918  }
1923  }
1924 
1925  static bool InReturnValues(interpreter::Register reg,
1927  int result_size);
1928 
1929  template <typename Function>
1930  void ForEachInput(Function&& f);
1931  template <typename Function>
1932  void ForEachInput(Function&& f) const;
1933 
1934  private:
1935 #ifdef DEBUG
1936  bool IsConsideredForResultLocation() const {
1937  switch (top_frame().type()) {
1939  // Interpreted frames obviously need a result location.
1940  return true;
1943  return false;
1945  // Normally if the function is going to be deoptimized then the top
1946  // frame should be an interpreted one, except for LazyDeoptContinuation
1947  // builtin.
1948  switch (top_frame().as_builtin_continuation().builtin_id()) {
1949  case Builtin::kGenericLazyDeoptContinuation:
1950  case Builtin::kGetIteratorWithFeedbackLazyDeoptContinuation:
1951  case Builtin::kCallIteratorWithFeedbackLazyDeoptContinuation:
1952  return true;
1953  default:
1954  return false;
1955  }
1956  }
1957  }
1958 #endif // DEBUG
1959 
1962 
1963  // The max code size is enforced by the various assemblers, but it's not
1964  // visible here, so static assert against the magic constant that we happen
1965  // to know is correct.
1966  static constexpr int kMaxCodeSize = 512 * MB;
1967  static constexpr unsigned int kUninitializedCallReturnPc =
1970  static_assert(kMaxCodeSize != kUninitializedCallReturnPc);
1971 
1972  // Lazy deopts can have at most two result registers -- temporarily three for
1973  // ForInPrepare.
1974  static_assert(ResultSizeField::kMax >= 3);
1975 
1977  uint32_t bitfield_;
1978 };
1979 
1981  public:
1983  enum Mode {
1986  };
1987 
1989  : catch_block_(), depth_(static_cast<int>(mode)), pc_offset_(-1) {}
1990 
1992  : catch_block_(catch_block_ref), depth_(depth), pc_offset_(-1) {
1995  }
1996 
1997  ExceptionHandlerInfo(BasicBlock* catch_block_ref, int depth)
1998  : catch_block_(catch_block_ref), depth_(depth), pc_offset_(-1) {}
1999 
2000  bool HasExceptionHandler() const { return depth_ != kNoExceptionHandler; }
2001 
2002  bool ShouldLazyDeopt() const { return depth_ == kLazyDeopt; }
2003 
2005 
2007 
2009 
2010  int depth() const {
2013  return depth_;
2014  }
2015 
2016  int pc_offset() const { return pc_offset_; }
2017  void set_pc_offset(int offset) {
2018  DCHECK_EQ(pc_offset_, -1);
2019  DCHECK_NE(offset, -1);
2020  pc_offset_ = offset;
2021  }
2022 
2023  private:
2026  int depth_;
2028 
2031 
2032  friend List;
2034 };
2035 
2036 // Dummy type for the initial raw allocation.
2038 
2039 namespace detail {
2040 // Helper for getting the static opcode of a Node subclass. This is in a
2041 // "detail" namespace rather than in NodeBase because we can't template
2042 // specialize outside of namespace scopes before C++17.
2043 template <class T>
2045 
2046 #define DEF_OPCODE_OF(Name) \
2047  template <> \
2048  struct opcode_of_helper<Name> { \
2049  static constexpr Opcode value = Opcode::k##Name; \
2050  };
2052 #undef DEF_OPCODE_OF
2053 
2054 template <typename T>
2055 constexpr T* ObjectPtrBeforeAddress(void* address) {
2056  char* address_as_char_ptr = reinterpret_cast<char*>(address);
2057  char* object_ptr_as_char_ptr = address_as_char_ptr - sizeof(T);
2058  return reinterpret_cast<T*>(object_ptr_as_char_ptr);
2059 }
2060 
2061 template <typename T>
2062 constexpr const T* ObjectPtrBeforeAddress(const void* address) {
2063  const char* address_as_char_ptr = reinterpret_cast<const char*>(address);
2064  const char* object_ptr_as_char_ptr = address_as_char_ptr - sizeof(T);
2065  return reinterpret_cast<const T*>(object_ptr_as_char_ptr);
2066 }
2067 
2068 } // namespace detail
2069 
2070 #define DEOPTIMIZE_REASON_FIELD \
2071  private: \
2072  using ReasonField = \
2073  NextBitField<DeoptimizeReason, base::bits::WhichPowerOfTwo<size_t>( \
2074  base::bits::RoundUpToPowerOfTwo32( \
2075  kDeoptimizeReasonCount))>; \
2076  \
2077  public: \
2078  DeoptimizeReason deoptimize_reason() const { \
2079  return ReasonField::decode(bitfield()); \
2080  }
2081 
2082 struct KnownNodeAspects;
2083 class NodeBase : public ZoneObject {
2084  private:
2085  // Bitfield specification.
2087  static_assert(OpcodeField::is_valid(kLastOpcode));
2094  static_assert(InputCountField::kShift == 32);
2095 
2096  protected:
2097  // Reserved for intermediate superclasses such as ValueNode.
2099  // Subclasses may use the remaining bitfield bits.
2100  template <class T, int size>
2102 
2103  static constexpr int kMaxInputs = InputCountField::kMax;
2104 
2105  public:
2106  template <class T>
2108 
2109  template <class Derived, typename... Args>
2110  static Derived* New(Zone* zone, std::initializer_list<ValueNode*> inputs,
2111  Args&&... args) {
2112  static_assert(Derived::kProperties.is_conversion(),
2113  "This method does not implicitly convert input types. Use "
2114  "MaglevGraphBuilder::AddNewNode instead or NodeBase::New and "
2115  "initialize and convert inputs manually.");
2116  Derived* node =
2117  Allocate<Derived>(zone, inputs.size(), std::forward<Args>(args)...);
2118 
2119  int i = 0;
2120  for (ValueNode* input : inputs) {
2122  node->set_input(i++, input);
2123  }
2124 
2125  return node;
2126  }
2127 
2128  // Inputs must be initialized manually.
2129  template <class Derived, typename... Args>
2130  static Derived* New(Zone* zone, size_t input_count, Args&&... args) {
2131  Derived* node =
2132  Allocate<Derived>(zone, input_count, std::forward<Args>(args)...);
2133  return node;
2134  }
2135 
2136  // Overwritten by subclasses.
2137  static constexpr OpProperties kProperties =
2139 
2140  constexpr Opcode opcode() const { return OpcodeField::decode(bitfield_); }
2141  constexpr OpProperties properties() const {
2143  }
2146  }
2147 
2148  inline void set_input(int index, ValueNode* node);
2149 
2150  template <class T>
2151  constexpr bool Is() const;
2152 
2153  template <class T>
2154  constexpr T* Cast() {
2155  DCHECK(Is<T>());
2156  return static_cast<T*>(this);
2157  }
2158  template <class T>
2159  constexpr const T* Cast() const {
2160  DCHECK(Is<T>());
2161  return static_cast<const T*>(this);
2162  }
2163  template <class T>
2164  constexpr T* TryCast() {
2165  return Is<T>() ? static_cast<T*>(this) : nullptr;
2166  }
2167 
2168  template <class T>
2169  constexpr const T* TryCast() const {
2170  return Is<T>() ? static_cast<const T*>(this) : nullptr;
2171  }
2172 
2173  constexpr bool has_inputs() const { return input_count() > 0; }
2174  constexpr int input_count() const {
2175  static_assert(InputCountField::kMax <= kMaxInt);
2176  return static_cast<int>(InputCountField::decode(bitfield_));
2177  }
2178 
2179  constexpr Input& input(int index) {
2181  return *(input_base() - index);
2182  }
2183  constexpr const Input& input(int index) const {
2185  return *(input_base() - index);
2186  }
2187 
2188  std::optional<int32_t> TryGetInt32ConstantInput(int index);
2189 
2190  // Input iterators, use like:
2191  //
2192  // for (Input& input : *node) { ... }
2193  constexpr auto begin() { return std::make_reverse_iterator(&input(-1)); }
2194  constexpr auto end() {
2195  return std::make_reverse_iterator(&input(input_count() - 1));
2196  }
2197 
2198  constexpr bool has_id() const { return id_ != kInvalidNodeId; }
2199  constexpr NodeIdT id() const {
2201  return id_;
2202  }
2203  void set_id(NodeIdT id) {
2206  id_ = id;
2207  }
2208 
2209  template <typename RegisterT>
2210  uint8_t num_temporaries_needed() const {
2211  if constexpr (std::is_same_v<RegisterT, Register>) {
2213  } else {
2215  }
2216  }
2217 
2218  template <typename RegisterT>
2220  return owner_or_temporaries_.temporaries<RegisterT>();
2221  }
2222  RegList& general_temporaries() { return temporaries<Register>(); }
2223  DoubleRegList& double_temporaries() { return temporaries<DoubleRegister>(); }
2224 
2225  template <typename RegisterT>
2227  owner_or_temporaries_.temporaries<RegisterT>() = list;
2228  }
2229 
2231 
2232  // Some parts of Maglev require a specific iteration order of the inputs (such
2233  // as UseMarkingProcessor::MarkInputUses or
2234  // StraightForwardRegisterAllocator::AssignInputs). For such cases,
2235  // `ForAllInputsInRegallocAssignmentOrder` can be called with a callback `f`
2236  // that will be called for each input in the "correct" order.
2237  template <typename Function>
2239 
2240  void Print(std::ostream& os, MaglevGraphLabeller*,
2241  bool skip_targets = false) const;
2242 
2243  // For GDB: Print any Node with `print node->Print()`.
2244  void Print() const;
2245 
2247  DCHECK(properties().can_eager_deopt() ||
2248  properties().is_deopt_checkpoint());
2249  DCHECK(!properties().can_lazy_deopt());
2250  return reinterpret_cast<EagerDeoptInfo*>(deopt_info_address());
2251  }
2252 
2254  DCHECK(properties().can_lazy_deopt());
2255  DCHECK(!properties().can_eager_deopt());
2256  return reinterpret_cast<LazyDeoptInfo*>(deopt_info_address());
2257  }
2258 
2260  DCHECK(properties().needs_register_snapshot());
2261  return *reinterpret_cast<RegisterSnapshot*>(register_snapshot_address());
2262  }
2263 
2265  DCHECK(properties().can_throw());
2266  return reinterpret_cast<ExceptionHandlerInfo*>(exception_handler_address());
2267  }
2268 
2270  DCHECK(properties().needs_register_snapshot());
2271  *reinterpret_cast<RegisterSnapshot*>(register_snapshot_address()) =
2272  snapshot;
2273  }
2274 
2275  inline void change_input(int index, ValueNode* node);
2276 
2278  DCHECK_EQ(opcode(), Opcode::kPhi);
2280  bitfield_, properties().WithNewValueRepresentation(new_repr));
2281  }
2282 
2283  void set_opcode(Opcode new_opcode) {
2284  bitfield_ = OpcodeField::update(bitfield_, new_opcode);
2285  }
2286 
2287  void CopyEagerDeoptInfoOf(NodeBase* other, Zone* zone) {
2288  new (eager_deopt_info())
2289  EagerDeoptInfo(zone, other->eager_deopt_info()->top_frame(),
2290  other->eager_deopt_info()->feedback_to_update());
2291  }
2292 
2293  void SetEagerDeoptInfo(Zone* zone, DeoptFrame deopt_frame,
2294  compiler::FeedbackSource feedback_to_update =
2296  DCHECK(properties().can_eager_deopt() ||
2297  properties().is_deopt_checkpoint());
2298  new (eager_deopt_info())
2299  EagerDeoptInfo(zone, deopt_frame, feedback_to_update);
2300  }
2301 
2302  template <typename NodeT>
2303  void OverwriteWith() {
2304  OverwriteWith(NodeBase::opcode_of<NodeT>, NodeT::kProperties);
2305  }
2306 
2308  Opcode new_opcode,
2309  std::optional<OpProperties> maybe_new_properties = std::nullopt) {
2310  OpProperties new_properties = maybe_new_properties.has_value()
2311  ? maybe_new_properties.value()
2312  : StaticPropertiesForOpcode(new_opcode);
2313 #ifdef DEBUG
2314  CheckCanOverwriteWith(new_opcode, new_properties);
2315 #endif
2316  set_opcode(new_opcode);
2317  set_properties(new_properties);
2318  }
2319 
2320  inline void OverwriteWithIdentityTo(ValueNode* node);
2321 
2322  auto options() const { return std::tuple{}; }
2323 
2326 
2327  void set_owner(BasicBlock* block) { owner_or_temporaries_ = block; }
2328 
2330 
2332 
2333  protected:
2334  explicit NodeBase(uint64_t bitfield) : bitfield_(bitfield) {}
2335 
2336  // Allow updating bits above NextBitField from subclasses
2337  constexpr uint64_t bitfield() const { return bitfield_; }
2338  void set_bitfield(uint64_t new_bitfield) {
2339 #ifdef DEBUG
2340  // Make sure that all the base bitfield bits (all bits before the next
2341  // bitfield start, excluding any spare bits) are equal in the new value.
2342  const uint64_t base_bitfield_mask =
2343  ((uint64_t{1} << NextBitField<bool, 1>::kShift) - 1) &
2344  ~ReservedField::kMask;
2345  DCHECK_EQ(bitfield_ & base_bitfield_mask,
2346  new_bitfield & base_bitfield_mask);
2347 #endif
2348  bitfield_ = new_bitfield;
2349  }
2350 
2351  constexpr Input* input_base() {
2352  return detail::ObjectPtrBeforeAddress<Input>(this);
2353  }
2354  constexpr const Input* input_base() const {
2355  return detail::ObjectPtrBeforeAddress<Input>(this);
2356  }
2357  Input* last_input() { return &input(input_count() - 1); }
2358  const Input* last_input() const { return &input(input_count() - 1); }
2359 
2361  return reinterpret_cast<Address>(last_input());
2362  }
2363 
2364  inline void initialize_input_null(int index);
2365 
2366  // For nodes that don't have data past the input, allow trimming the input
2367  // count. This is used by Phis to reduce inputs when merging in dead control
2368  // flow.
2369  void reduce_input_count(int num = 1) {
2370  DCHECK_EQ(opcode(), Opcode::kPhi);
2371  DCHECK_GE(input_count(), num);
2372  DCHECK(!properties().can_lazy_deopt());
2373  DCHECK(!properties().can_eager_deopt());
2375  }
2376 
2377  // Specify that there need to be a certain number of registers free (i.e.
2378  // usable as scratch registers) on entry into this node.
2379  //
2380  // Does not include any registers requested by RequireSpecificTemporary.
2382  DCHECK_EQ(num_temporaries_needed<Register>(), 0);
2384  }
2385 
2387  DCHECK_EQ(num_temporaries_needed<DoubleRegister>(), 0);
2389  }
2390 
2391  // Require that a specific register is free (and therefore clobberable) by the
2392  // entry into this node.
2394  general_temporaries().set(reg);
2395  }
2396 
2398  double_temporaries().set(reg);
2399  }
2400 
2401  private:
2402  template <class Derived, typename... Args>
2403  static Derived* Allocate(Zone* zone, size_t input_count, Args&&... args) {
2404  static_assert(
2405  !Derived::kProperties.can_eager_deopt() ||
2406  !Derived::kProperties.can_lazy_deopt(),
2407  "The current deopt info representation, at the end of inputs, requires "
2408  "that we cannot have both lazy and eager deopts on a node. If we ever "
2409  "need this, we have to update accessors to check node->properties() "
2410  "for which deopts are active.");
2411  constexpr size_t size_before_inputs =
2412  ExceptionHandlerInfoSize(Derived::kProperties) +
2413  RegisterSnapshotSize(Derived::kProperties) +
2414  EagerDeoptInfoSize(Derived::kProperties) +
2415  LazyDeoptInfoSize(Derived::kProperties);
2416 
2417  static_assert(IsAligned(size_before_inputs, alignof(Input)));
2418  const size_t size_before_node =
2419  size_before_inputs + input_count * sizeof(Input);
2420 
2421  DCHECK(IsAligned(size_before_inputs, alignof(Derived)));
2422  const size_t size = size_before_node + sizeof(Derived);
2423  intptr_t raw_buffer =
2424  reinterpret_cast<intptr_t>(zone->Allocate<NodeWithInlineInputs>(size));
2425 #ifdef DEBUG
2426  memset(reinterpret_cast<void*>(raw_buffer), 0, size);
2427 #endif
2428 
2429  void* node_buffer = reinterpret_cast<void*>(raw_buffer + size_before_node);
2430  uint64_t bitfield = OpcodeField::encode(opcode_of<Derived>) |
2431  OpPropertiesField::encode(Derived::kProperties) |
2433  Derived* node =
2434  new (node_buffer) Derived(bitfield, std::forward<Args>(args)...);
2435  return node;
2436  }
2437 
2439  return RoundUp<alignof(Input)>(
2440  properties.can_throw() ? sizeof(ExceptionHandlerInfo) : 0);
2441  }
2442 
2443  static constexpr size_t RegisterSnapshotSize(OpProperties properties) {
2444  return RoundUp<alignof(Input)>(
2446  }
2447 
2448  static constexpr size_t EagerDeoptInfoSize(OpProperties properties) {
2449  return RoundUp<alignof(Input)>(
2451  ? sizeof(EagerDeoptInfo)
2452  : 0);
2453  }
2454 
2455  static constexpr size_t LazyDeoptInfoSize(OpProperties properties) {
2456  return RoundUp<alignof(Input)>(
2457  properties.can_lazy_deopt() ? sizeof(LazyDeoptInfo) : 0);
2458  }
2459 
2460  // Returns the position of deopt info if it exists, otherwise returns
2461  // its position as if DeoptInfo size were zero.
2463  DCHECK(!properties().can_eager_deopt() || !properties().can_lazy_deopt());
2464  size_t extra =
2466  return last_input_address() - extra;
2467  }
2468 
2469  // Returns the position of register snapshot if it exists, otherwise returns
2470  // its position as if RegisterSnapshot size were zero.
2472  size_t extra = RegisterSnapshotSize(properties());
2473  return deopt_info_address() - extra;
2474  }
2475 
2476  // Returns the position of exception handler info if it exists, otherwise
2477  // returns its position as if ExceptionHandlerInfo size were zero.
2479  size_t extra = ExceptionHandlerInfoSize(properties());
2480  return register_snapshot_address() - extra;
2481  }
2482 
2483  void CheckCanOverwriteWith(Opcode new_opcode, OpProperties new_properties);
2484 
2485  uint64_t bitfield_;
2487 
2489  BasicBlock* owner() const {
2490  DCHECK_EQ(state_, State::kOwner);
2491  return store_.owner_;
2492  }
2493 
2494  template <typename RegisterT>
2496  DCHECK_EQ(state_, State::kReglist);
2497  if constexpr (std::is_same_v<RegisterT, Register>) {
2498  return store_.regs_.temporaries_;
2499  } else {
2501  }
2502  }
2503 
2505 #ifdef DEBUG
2506  DCHECK(state_ == State::kNull || state_ == State::kOwner);
2507  state_ = State::kOwner;
2508 #endif
2509  return store_.owner_ = owner;
2510  }
2511 
2512  void InitReglist() {
2513 #ifdef DEBUG
2514  DCHECK(state_ == State::kNull || state_ == State::kOwner);
2515  state_ = State::kReglist;
2516 #endif
2519  }
2520 
2521  private:
2522  struct Regs {
2525  };
2526  union Store {
2530  };
2532 #ifdef DEBUG
2533  enum class State{
2534  kNull,
2535  kOwner,
2536  kReglist,
2537  };
2538  State state_ = State::kNull;
2539 #endif
2540  };
2541 
2543 
2544  NodeBase() = delete;
2545  NodeBase(const NodeBase&) = delete;
2546  NodeBase(NodeBase&&) = delete;
2547  NodeBase& operator=(const NodeBase&) = delete;
2549 };
2550 
2551 template <class T>
2552 constexpr bool NodeBase::Is() const {
2553  return opcode() == opcode_of<T>;
2554 }
2555 
2556 // Specialized sub-hierarchy type checks.
2557 template <>
2558 constexpr bool NodeBase::Is<ValueNode>() const {
2559  return IsValueNode(opcode());
2560 }
2561 template <>
2562 constexpr bool NodeBase::Is<ControlNode>() const {
2563  return IsControlNode(opcode());
2564 }
2565 template <>
2566 constexpr bool NodeBase::Is<BranchControlNode>() const {
2567  return IsBranchControlNode(opcode());
2568 }
2569 template <>
2570 constexpr bool NodeBase::Is<ConditionalControlNode>() const {
2571  return IsConditionalControlNode(opcode());
2572 }
2573 template <>
2574 constexpr bool NodeBase::Is<UnconditionalControlNode>() const {
2576 }
2577 template <>
2578 constexpr bool NodeBase::Is<TerminalControlNode>() const {
2579  return IsTerminalControlNode(opcode());
2580 }
2581 
2582 void CheckValueInputIs(const NodeBase* node, int i,
2583  ValueRepresentation expected,
2584  MaglevGraphLabeller* graph_labeller);
2585 
2586 // The Node class hierarchy contains all non-control nodes.
2587 class Node : public NodeBase {
2588  public:
2589  inline ValueLocation& result();
2590 
2591  static constexpr bool participate_in_cse(Opcode op) {
2593  !IsConstantNode(op) && !IsControlNode(op) && !IsZeroCostNode(op) &&
2594  // The following are already precisely tracked by known_node_aspects
2595  // and tracking them with CSE would just waste time.
2596  op != Opcode::kCheckMaps;
2597  }
2598 
2599  static constexpr bool needs_epoch_check(Opcode op) {
2600  return StaticPropertiesForOpcode(op).can_read();
2601  }
2602 
2603  protected:
2604  using NodeBase::NodeBase;
2605 };
2606 
2607 // All non-control nodes with a result.
2608 class ValueNode : public Node {
2609  private:
2611 
2612  protected:
2614 
2615  public:
2617  const ValueLocation& result() const { return result_; }
2618 
2619  int use_count() const {
2620  // Invalid to check use_count externally once an id is allocated.
2621  DCHECK(!has_id());
2622  return use_count_;
2623  }
2624  bool is_used() const { return use_count_ > 0; }
2625  bool unused_inputs_were_visited() const { return use_count_ == -1; }
2626  void add_use() {
2627  // Make sure a saturated use count won't overflow.
2629  use_count_++;
2630  }
2631  inline void remove_use();
2632  // Avoid revisiting nodes when processing an unused node's inputs, by marking
2633  // it as visited.
2635  DCHECK_EQ(use_count_, 0);
2636  use_count_ = -1;
2637  }
2638 
2640 
2642 
2643  bool has_hint() { return !hint_.IsInvalid(); }
2644 
2645  template <typename RegisterT>
2646  RegisterT GetRegisterHint() {
2647  if (hint_.IsInvalid()) return RegisterT::no_reg();
2648  return RegisterT::from_code(
2649  compiler::UnallocatedOperand::cast(hint_).fixed_register_index());
2650  }
2651 
2653  DCHECK(hint_.IsInvalid() || hint_.IsUnallocated());
2654  return hint_;
2655  }
2656 
2657  bool is_loadable() const {
2658  DCHECK_EQ(state_, kSpill);
2659  return spill_.IsConstant() || spill_.IsAnyStackSlot();
2660  }
2661 
2662  bool is_spilled() const {
2663  DCHECK_EQ(state_, kSpill);
2664  return spill_.IsAnyStackSlot();
2665  }
2666 
2667  void SetNoSpill();
2668  void SetConstantLocation();
2669 
2670  /* For constants only. */
2675  DirectHandle<Object> Reify(LocalIsolate* isolate) const;
2676 
2678 #ifdef DEBUG
2679  if (state_ == kLastUse) {
2680  state_ = kSpill;
2681  } else {
2682  DCHECK(!is_loadable());
2683  }
2684 #endif // DEBUG
2686  DCHECK(operand.IsAnyStackSlot());
2687  spill_ = operand;
2689  }
2690 
2692  DCHECK(is_spilled());
2694  }
2695 
2697  DCHECK_EQ(state_, kSpill);
2698  DCHECK(is_loadable());
2699  return spill_;
2700  }
2701 
2702  void record_next_use(NodeIdT id, InputLocation* input_location) {
2703  DCHECK_EQ(state_, kLastUse);
2705  DCHECK_LT(start_id(), id);
2707  end_id_ = id;
2709  last_uses_next_use_id_ = input_location->get_next_use_id_address();
2711  }
2712 
2713  struct LiveRange {
2715  NodeIdT end = kInvalidNodeId; // Inclusive.
2716  };
2717 
2718  bool has_valid_live_range() const { return end_id_ != 0; }
2719  LiveRange live_range() const { return {start_id(), end_id_}; }
2720  NodeIdT current_next_use() const { return next_use_; }
2721 
2722  // The following methods should only be used during register allocation, to
2723  // mark the _current_ state of this Node according to the register allocator.
2725 
2726  bool has_no_more_uses() const { return next_use_ == kInvalidNodeId; }
2727 
2728  constexpr bool use_double_register() const {
2730  }
2731 
2732  constexpr bool is_tagged() const {
2733  return (properties().value_representation() ==
2735  }
2736 
2737 #ifdef V8_COMPRESS_POINTERS
2738  constexpr bool decompresses_tagged_result() const {
2740  }
2741 
2742  void SetTaggedResultNeedsDecompress() {
2743  static_assert(PointerCompressionIsEnabled());
2744 
2745  DCHECK_IMPLIES(!Is<Identity>(), is_tagged());
2746  DCHECK_IMPLIES(Is<Identity>(), input(0).node()->is_tagged());
2748  if (Is<Phi>()) {
2749  for (Input& input : *this) {
2750  // Avoid endless recursion by terminating on values already marked.
2751  if (input.node()->decompresses_tagged_result()) continue;
2752  input.node()->SetTaggedResultNeedsDecompress();
2753  }
2754  } else if (Is<Identity>()) {
2755  DCHECK_EQ(input_count(), 0);
2756  input(0).node()->SetTaggedResultNeedsDecompress();
2757  }
2758  }
2759 #else
2760  constexpr bool decompresses_tagged_result() const { return false; }
2761 #endif
2762 
2764  return properties().value_representation();
2765  }
2766 
2768  switch (properties().value_representation()) {
2780  }
2781  }
2782 
2783  compiler::OptionalHeapObjectRef TryGetConstant(
2785 
2787 
2789  return NodeTypeIs(GetStaticType(broker), type);
2790  }
2791 
2793  if (use_double_register()) {
2795  } else {
2797  }
2798  }
2799 
2800  void AddRegister(Register reg) {
2803  }
2807  }
2808 
2812  }
2816  }
2817 
2818  template <typename T>
2820 
2821  int num_registers() const {
2822  if (use_double_register()) {
2824  }
2825  return registers_with_result_.Count();
2826  }
2827  bool has_register() const {
2828  if (use_double_register()) {
2830  }
2832  }
2833  bool is_in_register(Register reg) const {
2835  return registers_with_result_.has(reg);
2836  }
2837  bool is_in_register(DoubleRegister reg) const {
2839  return double_registers_with_result_.has(reg);
2840  }
2841 
2842  template <typename T>
2844  if constexpr (std::is_same_v<T, DoubleRegister>) {
2847  } else {
2849  return registers_with_result_;
2850  }
2851  }
2852 
2854  if (has_register()) {
2857  FirstRegisterCode());
2858  }
2859  CHECK(is_loadable());
2860  return spill_;
2861  }
2862 
2863  protected:
2864  explicit ValueNode(uint64_t bitfield)
2865  : Node(bitfield),
2867  hint_(compiler::InstructionOperand()),
2868  use_count_(0)
2869 #ifdef DEBUG
2870  ,
2871  state_(kLastUse)
2872 #endif // DEBUG
2873  {
2875  }
2876 
2877  int FirstRegisterCode() const {
2878  if (use_double_register()) {
2880  }
2881  return registers_with_result_.first().code();
2882  }
2883 
2884  // Rename for better pairing with `end_id`.
2885  NodeIdT start_id() const { return id(); }
2886 
2890  union {
2893  };
2894  union {
2895  // Pointer to the current last use's next_use_id field. Most of the time
2896  // this will be a pointer to an Input's next_use_id_ field, but it's
2897  // initialized to this node's next_use_ to track the first use.
2900  };
2902  // TODO(leszeks): Union this into another field.
2904 #ifdef DEBUG
2905  enum {kLastUse, kSpill} state_;
2906 #endif // DEBUG
2907 };
2908 
2910  // Should already be null in debug, make sure it's null on release too.
2911  DCHECK_EQ(input(index).node(), nullptr);
2912  new (&input(index)) Input(nullptr);
2913 }
2914 
2915 inline void NodeBase::set_input(int index, ValueNode* node) {
2916  DCHECK_NOT_NULL(node);
2917  DCHECK_EQ(input(index).node(), nullptr);
2918  node->add_use();
2919  new (&input(index)) Input(node);
2920 }
2921 
2922 template <>
2925  return std::exchange(registers_with_result_, kEmptyRegList);
2926 }
2927 
2928 template <>
2931  return std::exchange(double_registers_with_result_, kEmptyDoubleRegList);
2932 }
2933 
2935  DCHECK(Is<ValueNode>());
2936  return Cast<ValueNode>()->result();
2937 }
2938 
2939 // Mixin for a node with known class (and therefore known opcode and static
2940 // properties), but possibly unknown numbers of inputs.
2941 template <typename Base, typename Derived>
2942 class NodeTMixin : public Base {
2943  public:
2944  // Shadowing for static knowledge.
2945  constexpr Opcode opcode() const { return NodeBase::opcode_of<Derived>; }
2946  constexpr const OpProperties& properties() const {
2947  return Derived::kProperties;
2948  }
2949 
2950  template <typename... Args>
2951  static Derived* New(Zone* zone, std::initializer_list<ValueNode*> inputs,
2952  Args&&... args) {
2953  return NodeBase::New<Derived>(zone, inputs, std::forward<Args>...);
2954  }
2955  template <typename... Args>
2956  static Derived* New(Zone* zone, size_t input_count, Args&&... args) {
2957  return NodeBase::New<Derived>(zone, input_count, std::forward<Args>...);
2958  }
2959 
2960  protected:
2961  template <typename... Args>
2962  explicit NodeTMixin(uint64_t bitfield, Args&&... args)
2963  : Base(bitfield, std::forward<Args>(args)...) {
2964  DCHECK_EQ(this->NodeBase::opcode(), NodeBase::opcode_of<Derived>);
2965  DCHECK_EQ(this->NodeBase::properties(), Derived::kProperties);
2966  }
2967 };
2968 
2969 namespace detail {
2970 // Helper class for defining input types as a std::array, but without
2971 // accidental initialisation with the wrong sized initializer_list.
2972 template <size_t Size>
2973 class ArrayWrapper : public std::array<ValueRepresentation, Size> {
2974  public:
2975  template <typename... Args>
2976  explicit constexpr ArrayWrapper(Args&&... args)
2977  : std::array<ValueRepresentation, Size>({args...}) {
2978  static_assert(sizeof...(args) == Size);
2979  }
2980 };
2982 } // namespace detail
2983 
2984 // Mixin for a node with known class (and therefore known opcode and static
2985 // properties), and known numbers of inputs.
2986 template <size_t InputCount, typename Base, typename Derived>
2987 class FixedInputNodeTMixin : public NodeTMixin<Base, Derived> {
2988  public:
2989  static constexpr size_t kInputCount = InputCount;
2990 
2991  // Shadowing for static knowledge.
2992  constexpr bool has_inputs() const { return input_count() > 0; }
2993  constexpr uint16_t input_count() const { return kInputCount; }
2994  constexpr auto end() {
2995  return std::make_reverse_iterator(&this->input(input_count() - 1));
2996  }
2997 
2998  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const {
2999  if constexpr (kInputCount != 0) {
3000  static_assert(
3001  std::is_same_v<const InputTypes, decltype(Derived::kInputTypes)>);
3002  static_assert(kInputCount == Derived::kInputTypes.size());
3003  for (int i = 0; i < static_cast<int>(kInputCount); ++i) {
3004  CheckValueInputIs(this, i, Derived::kInputTypes[i], graph_labeller);
3005  }
3006  }
3007  }
3008 
3009 #ifdef V8_COMPRESS_POINTERS
3010  void MarkTaggedInputsAsDecompressing() const {
3011  if constexpr (kInputCount != 0) {
3012  static_assert(
3013  std::is_same_v<const InputTypes, decltype(Derived::kInputTypes)>);
3014  static_assert(kInputCount == Derived::kInputTypes.size());
3015  for (int i = 0; i < static_cast<int>(kInputCount); ++i) {
3016  if (Derived::kInputTypes[i] == ValueRepresentation::kTagged) {
3017  ValueNode* input_node = this->input(i).node();
3018  input_node->SetTaggedResultNeedsDecompress();
3019  }
3020  }
3021  }
3022  }
3023 #endif
3024 
3025  protected:
3028 
3029  template <typename... Args>
3030  explicit FixedInputNodeTMixin(uint64_t bitfield, Args&&... args)
3031  : NodeTMixin<Base, Derived>(bitfield, std::forward<Args>(args)...) {
3032  DCHECK_EQ(this->NodeBase::input_count(), kInputCount);
3033  }
3034 };
3035 
3036 template <class T, class = void>
3037 struct IsFixedInputNode : public std::false_type {};
3038 template <class T>
3039 struct IsFixedInputNode<T, std::void_t<decltype(T::kInputCount)>>
3040  : public std::true_type {};
3041 
3042 template <class Derived>
3044 
3045 template <class Derived>
3047 
3048 template <size_t InputCount, class Derived>
3051 
3052 template <size_t InputCount, class Derived>
3055 
3056 class Identity : public FixedInputValueNodeT<1, Identity> {
3058 
3059  public:
3061 
3062  explicit Identity(uint64_t bitfield) : Base(bitfield) {}
3063 
3065  // Identity is valid for all input types.
3066  }
3067 #ifdef V8_COMPRESS_POINTERS
3068  void MarkTaggedInputsAsDecompressing() {
3069  // Do not mark inputs as decompressing here, since we don't yet know whether
3070  // this Phi needs decompression. Instead, let
3071  // Node::SetTaggedResultNeedsDecompress pass through phis.
3072  }
3073 #endif
3076  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3077 };
3078 
3079 template <class Derived, Operation kOperation>
3080 class UnaryWithFeedbackNode : public FixedInputValueNodeT<1, Derived> {
3082 
3083  public:
3084  // The implementation currently calls runtime.
3086  static constexpr
3088 
3089  static constexpr int kOperandIndex = 0;
3092 
3093  protected:
3094  explicit UnaryWithFeedbackNode(uint64_t bitfield,
3096  : Base(bitfield), feedback_(feedback) {}
3097 
3100  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3101 
3103 };
3104 
3105 template <class Derived, Operation kOperation>
3106 class BinaryWithFeedbackNode : public FixedInputValueNodeT<2, Derived> {
3108 
3109  public:
3110  // The implementation currently calls runtime.
3112  static constexpr typename Base::InputTypes kInputTypes{
3114 
3115  static constexpr int kLeftIndex = 0;
3116  static constexpr int kRightIndex = 1;
3120 
3121  protected:
3122  BinaryWithFeedbackNode(uint64_t bitfield,
3124  : Base(bitfield), feedback_(feedback) {}
3125 
3128  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3129 
3131 };
3132 
3133 #define DEF_OPERATION_WITH_FEEDBACK_NODE(Name, Super, OpName) \
3134  class Name : public Super<Name, Operation::k##OpName> { \
3135  using Base = Super<Name, Operation::k##OpName>; \
3136  \
3137  public: \
3138  Name(uint64_t bitfield, const compiler::FeedbackSource& feedback) \
3139  : Base(bitfield, feedback) {} \
3140  int MaxCallStackArgs() const { return 0; } \
3141  void SetValueLocationConstraints(); \
3142  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
3143  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
3144  };
3145 
3146 #define DEF_UNARY_WITH_FEEDBACK_NODE(Name) \
3147  DEF_OPERATION_WITH_FEEDBACK_NODE(Generic##Name, UnaryWithFeedbackNode, Name)
3148 #define DEF_BINARY_WITH_FEEDBACK_NODE(Name) \
3149  DEF_OPERATION_WITH_FEEDBACK_NODE(Generic##Name, BinaryWithFeedbackNode, Name)
3153 #undef DEF_UNARY_WITH_FEEDBACK_NODE
3154 #undef DEF_BINARY_WITH_FEEDBACK_NODE
3155 #undef DEF_OPERATION_WITH_FEEDBACK_NODE
3156 
3157 template <class Derived, Operation kOperation>
3160 
3161  public:
3162  static constexpr OpProperties kProperties =
3164  static constexpr typename Base::InputTypes kInputTypes{
3166 
3167  static constexpr int kLeftIndex = 0;
3168  static constexpr int kRightIndex = 1;
3171 
3172  protected:
3173  explicit Int32BinaryWithOverflowNode(uint64_t bitfield) : Base(bitfield) {}
3174 
3175  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3176 };
3177 
3178 #define DEF_OPERATION_NODE(Name, Super, OpName) \
3179  class Name : public Super<Name, Operation::k##OpName> { \
3180  using Base = Super<Name, Operation::k##OpName>; \
3181  \
3182  public: \
3183  explicit Name(uint64_t bitfield) : Base(bitfield) {} \
3184  void SetValueLocationConstraints(); \
3185  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
3186  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
3187  };
3188 
3189 #define DEF_INT32_BINARY_WITH_OVERFLOW_NODE(Name) \
3190  DEF_OPERATION_NODE(Int32##Name##WithOverflow, Int32BinaryWithOverflowNode, \
3191  Name)
3197 #undef DEF_INT32_BINARY_WITH_OVERFLOW_NODE
3198 
3199 template <class Derived, Operation kOperation>
3200 class Int32BinaryNode : public FixedInputValueNodeT<2, Derived> {
3202 
3203  public:
3205  static constexpr typename Base::InputTypes kInputTypes{
3207 
3208  static constexpr int kLeftIndex = 0;
3209  static constexpr int kRightIndex = 1;
3212 
3213  protected:
3214  explicit Int32BinaryNode(uint64_t bitfield) : Base(bitfield) {}
3215 };
3216 
3217 #define DEF_INT32_BINARY_NODE(Name) \
3218  DEF_OPERATION_NODE(Int32##Name, Int32BinaryNode, Name)
3219 DEF_INT32_BINARY_NODE(BitwiseAnd)
3220 DEF_INT32_BINARY_NODE(BitwiseOr)
3221 DEF_INT32_BINARY_NODE(BitwiseXor)
3222 DEF_INT32_BINARY_NODE(ShiftLeft)
3223 DEF_INT32_BINARY_NODE(ShiftRight)
3224 #undef DEF_INT32_BINARY_NODE
3225 
3226 class Int32BitwiseNot : public FixedInputValueNodeT<1, Int32BitwiseNot> {
3228 
3229  public:
3230  explicit Int32BitwiseNot(uint64_t bitfield) : Base(bitfield) {}
3231 
3233  static constexpr
3235 
3236  static constexpr int kValueIndex = 0;
3238 
3241  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3242 };
3243 
3244 template <class Derived, Operation kOperation>
3247 
3248  public:
3249  static constexpr OpProperties kProperties =
3251  static constexpr
3253 
3254  static constexpr int kValueIndex = 0;
3256 
3257  protected:
3258  explicit Int32UnaryWithOverflowNode(uint64_t bitfield) : Base(bitfield) {}
3259 };
3260 
3261 #define DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Name) \
3262  DEF_OPERATION_NODE(Int32##Name##WithOverflow, Int32UnaryWithOverflowNode, \
3263  Name)
3264 
3268 #undef DEF_INT32_UNARY_WITH_OVERFLOW_NODE
3269 
3271  : public FixedInputValueNodeT<2, Int32ShiftRightLogical> {
3273 
3274  public:
3275  explicit Int32ShiftRightLogical(uint64_t bitfield) : Base(bitfield) {}
3276 
3277  // Unlike the other Int32 nodes, logical right shift returns a Uint32.
3279  static constexpr typename Base::InputTypes kInputTypes{
3281 
3282  static constexpr int kLeftIndex = 0;
3283  static constexpr int kRightIndex = 1;
3286 
3289  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3290 };
3291 
3292 class Int32Compare : public FixedInputValueNodeT<2, Int32Compare> {
3294 
3295  public:
3296  explicit Int32Compare(uint64_t bitfield, Operation operation)
3297  : Base(OperationBitField::update(bitfield, operation)) {}
3298 
3301 
3302  static constexpr int kLeftIndex = 0;
3303  static constexpr int kRightIndex = 1;
3306 
3307  constexpr Operation operation() const {
3308  return OperationBitField::decode(bitfield());
3309  }
3310 
3313  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3314 
3315  auto options() const { return std::tuple{operation()}; }
3316 
3317  private:
3318  using OperationBitField = NextBitField<Operation, 5>;
3319 };
3320 
3321 class Int32ToBoolean : public FixedInputValueNodeT<1, Int32ToBoolean> {
3323 
3324  public:
3325  explicit Int32ToBoolean(uint64_t bitfield, bool flip)
3326  : Base(FlipBitField::update(bitfield, flip)) {}
3327 
3329 
3330  Input& value() { return Node::input(0); }
3331 
3332  constexpr bool flip() const { return FlipBitField::decode(bitfield()); }
3333 
3336  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3337 
3338  auto options() const { return std::tuple{flip()}; }
3339 
3340  private:
3341  using FlipBitField = NextBitField<bool, 1>;
3342 };
3343 
3344 class IntPtrToBoolean : public FixedInputValueNodeT<1, IntPtrToBoolean> {
3346 
3347  public:
3348  explicit IntPtrToBoolean(uint64_t bitfield, bool flip)
3349  : Base(FlipBitField::update(bitfield, flip)) {}
3350 
3352 
3353  Input& value() { return Node::input(0); }
3354 
3355  constexpr bool flip() const { return FlipBitField::decode(bitfield()); }
3356 
3359  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3360 
3361  auto options() const { return std::tuple{flip()}; }
3362 
3363  private:
3364  using FlipBitField = NextBitField<bool, 1>;
3365 };
3366 
3368  : public FixedInputValueNodeT<1, CheckedSmiIncrement> {
3370 
3371  public:
3372  explicit CheckedSmiIncrement(uint64_t bitfield) : Base(bitfield) {}
3373 
3375  static constexpr
3377 
3378  static constexpr int kValueIndex = 0;
3380 
3383  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3384 };
3385 
3387  : public FixedInputValueNodeT<1, CheckedSmiDecrement> {
3389 
3390  public:
3391  explicit CheckedSmiDecrement(uint64_t bitfield) : Base(bitfield) {}
3392 
3394  static constexpr
3396 
3397  static constexpr int kValueIndex = 0;
3399 
3402  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3403 };
3404 
3405 template <class Derived, Operation kOperation>
3406 class Float64BinaryNode : public FixedInputValueNodeT<2, Derived> {
3408 
3409  public:
3411  static constexpr typename Base::InputTypes kInputTypes{
3413 
3414  static constexpr int kLeftIndex = 0;
3415  static constexpr int kRightIndex = 1;
3418 
3419  protected:
3420  explicit Float64BinaryNode(uint64_t bitfield) : Base(bitfield) {}
3421 
3422  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3423 };
3424 
3425 #define DEF_OPERATION_NODE_WITH_CALL(Name, Super, OpName) \
3426  class Name : public Super<Name, Operation::k##OpName> { \
3427  using Base = Super<Name, Operation::k##OpName>; \
3428  \
3429  public: \
3430  explicit Name(uint64_t bitfield) : Base(bitfield) {} \
3431  int MaxCallStackArgs() const; \
3432  void SetValueLocationConstraints(); \
3433  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
3434  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
3435  };
3436 
3437 template <class Derived, Operation kOperation>
3440 
3441  public:
3442  static constexpr OpProperties kProperties =
3444  static constexpr typename Base::InputTypes kInputTypes{
3446 
3447  static constexpr int kLeftIndex = 0;
3448  static constexpr int kRightIndex = 1;
3451 
3452  protected:
3453  explicit Float64BinaryNodeWithCall(uint64_t bitfield) : Base(bitfield) {}
3454 
3455  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3456 };
3457 
3458 #define DEF_FLOAT64_BINARY_NODE(Name) \
3459  DEF_OPERATION_NODE(Float64##Name, Float64BinaryNode, Name)
3460 #define DEF_FLOAT64_BINARY_NODE_WITH_CALL(Name) \
3461  DEF_OPERATION_NODE_WITH_CALL(Float64##Name, Float64BinaryNodeWithCall, Name)
3464 DEF_FLOAT64_BINARY_NODE(Multiply)
3466 #if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_ARM) || \
3467  defined(V8_TARGET_ARCH_RISCV64)
3468 // On Arm/Arm64/Riscv64, floating point modulus is implemented with a call to a
3469 // C++ function, while on x64, it's implemented natively without call.
3471 #else
3472 DEF_FLOAT64_BINARY_NODE(Modulus)
3473 #endif
3475 #undef DEF_FLOAT64_BINARY_NODE
3476 #undef DEF_FLOAT64_BINARY_NODE_WITH_CALL
3477 
3478 #undef DEF_OPERATION_NODE
3479 #undef DEF_OPERATION_NODE_WITH_CALL
3480 
3481 class Float64Compare : public FixedInputValueNodeT<2, Float64Compare> {
3483 
3484  public:
3485  explicit Float64Compare(uint64_t bitfield, Operation operation)
3486  : Base(OperationBitField::update(bitfield, operation)) {}
3487 
3490 
3491  static constexpr int kLeftIndex = 0;
3492  static constexpr int kRightIndex = 1;
3495 
3496  constexpr Operation operation() const {
3497  return OperationBitField::decode(bitfield());
3498  }
3499 
3502  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3503 
3504  auto options() const { return std::tuple{operation()}; }
3505 
3506  private:
3507  using OperationBitField = NextBitField<Operation, 5>;
3508 };
3509 
3510 class Float64ToBoolean : public FixedInputValueNodeT<1, Float64ToBoolean> {
3512 
3513  public:
3514  explicit Float64ToBoolean(uint64_t bitfield, bool flip)
3515  : Base(FlipBitField::update(bitfield, flip)) {}
3516 
3517  static constexpr Base::InputTypes kInputTypes{
3519 
3520  Input& value() { return Node::input(0); }
3521 
3522  constexpr bool flip() const { return FlipBitField::decode(bitfield()); }
3523 
3526  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3527 
3528  auto options() const { return std::tuple{flip()}; }
3529 
3530  private:
3531  using FlipBitField = NextBitField<bool, 1>;
3532 };
3533 
3534 class Float64Negate : public FixedInputValueNodeT<1, Float64Negate> {
3536 
3537  public:
3538  explicit Float64Negate(uint64_t bitfield) : Base(bitfield) {}
3539 
3541  static constexpr
3543 
3544  Input& input() { return Node::input(0); }
3545 
3548  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3549 };
3550 
3551 #define IEEE_754_UNARY_LIST(V) \
3552  V(MathAcos, acos, Acos) \
3553  V(MathAcosh, acosh, Acosh) \
3554  V(MathAsin, asin, Asin) \
3555  V(MathAsinh, asinh, Asinh) \
3556  V(MathAtan, atan, Atan) \
3557  V(MathAtanh, atanh, Atanh) \
3558  V(MathCbrt, cbrt, Cbrt) \
3559  V(MathCos, cos, Cos) \
3560  V(MathCosh, cosh, Cosh) \
3561  V(MathExp, exp, Exp) \
3562  V(MathExpm1, expm1, Expm1) \
3563  V(MathLog, log, Log) \
3564  V(MathLog1p, log1p, Log1p) \
3565  V(MathLog10, log10, Log10) \
3566  V(MathLog2, log2, Log2) \
3567  V(MathSin, sin, Sin) \
3568  V(MathSinh, sinh, Sinh) \
3569  V(MathTan, tan, Tan) \
3570  V(MathTanh, tanh, Tanh)
3572  : public FixedInputValueNodeT<1, Float64Ieee754Unary> {
3574 
3575  public:
3576  enum class Ieee754Function : uint8_t {
3577 #define DECL_ENUM(MathName, ExtName, EnumName) k##EnumName,
3579 #undef DECL_ENUM
3580  };
3582  : Base(bitfield), ieee_function_(ieee_function) {}
3583 
3584  static constexpr OpProperties kProperties =
3586  static constexpr
3588 
3589  Input& input() { return Node::input(0); }
3590 
3591  int MaxCallStackArgs() const;
3594  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3595 
3596  auto options() const { return std::tuple{ieee_function_}; }
3597 
3600 
3601  private:
3603 };
3604 
3605 class CheckInt32IsSmi : public FixedInputNodeT<1, CheckInt32IsSmi> {
3607 
3608  public:
3609  explicit CheckInt32IsSmi(uint64_t bitfield) : Base(bitfield) {}
3610 
3612  static constexpr
3614 
3615  Input& input() { return Node::input(0); }
3616 
3619  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3620 };
3621 
3622 class CheckUint32IsSmi : public FixedInputNodeT<1, CheckUint32IsSmi> {
3624 
3625  public:
3626  explicit CheckUint32IsSmi(uint64_t bitfield) : Base(bitfield) {}
3627 
3629  static constexpr
3631 
3632  Input& input() { return Node::input(0); }
3633 
3636  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3637 };
3638 
3639 class CheckIntPtrIsSmi : public FixedInputNodeT<1, CheckIntPtrIsSmi> {
3641 
3642  public:
3643  explicit CheckIntPtrIsSmi(uint64_t bitfield) : Base(bitfield) {}
3644 
3646  static constexpr
3648 
3649  Input& input() { return Node::input(0); }
3650 
3653  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3654 };
3655 
3657  : public FixedInputNodeT<1, CheckHoleyFloat64IsSmi> {
3659 
3660  public:
3661  explicit CheckHoleyFloat64IsSmi(uint64_t bitfield) : Base(bitfield) {}
3662 
3664  static constexpr
3666 
3667  Input& input() { return Node::input(0); }
3668 
3671  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3672 };
3673 
3674 class CheckedSmiTagInt32 : public FixedInputValueNodeT<1, CheckedSmiTagInt32> {
3676 
3677  public:
3678  explicit CheckedSmiTagInt32(uint64_t bitfield) : Base(bitfield) {}
3679 
3680  static constexpr OpProperties kProperties =
3682  static constexpr
3684 
3685  Input& input() { return Node::input(0); }
3686 
3689  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3690 };
3691 
3692 // This is a check disguised as a conversion node so we can use it to override
3693 // untagging conversions.
3694 // TODO(olivf): Support overriding bigger with smaller instruction so we can use
3695 // CheckInt32IsSmi instead.
3697  : public FixedInputValueNodeT<1, CheckedSmiSizedInt32> {
3699 
3700  public:
3701  explicit CheckedSmiSizedInt32(uint64_t bitfield) : Base(bitfield) {}
3702 
3706  static constexpr
3708 
3709  Input& input() { return Node::input(0); }
3710 
3713  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3714 };
3715 
3717  : public FixedInputValueNodeT<1, CheckedSmiTagUint32> {
3719 
3720  public:
3721  explicit CheckedSmiTagUint32(uint64_t bitfield) : Base(bitfield) {}
3722 
3723  static constexpr OpProperties kProperties =
3725  static constexpr
3727 
3728  Input& input() { return Node::input(0); }
3729 
3732  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3733 };
3734 
3736  : public FixedInputValueNodeT<1, CheckedSmiTagIntPtr> {
3738 
3739  public:
3740  explicit CheckedSmiTagIntPtr(uint64_t bitfield) : Base(bitfield) {}
3741 
3742  static constexpr OpProperties kProperties =
3744  static constexpr
3746 
3747  Input& input() { return Node::input(0); }
3748 
3751  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3752 };
3753 
3754 // Input must guarantee to fit in a Smi.
3755 class UnsafeSmiTagInt32 : public FixedInputValueNodeT<1, UnsafeSmiTagInt32> {
3757 
3758  public:
3759  explicit UnsafeSmiTagInt32(uint64_t bitfield) : Base(bitfield) {}
3760 
3762  static constexpr
3764 
3765  Input& input() { return Node::input(0); }
3766 
3767 #ifdef V8_COMPRESS_POINTERS
3768  void MarkTaggedInputsAsDecompressing() {
3769  // No tagged inputs.
3770  }
3771 #endif
3772 
3775  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3776 };
3777 
3778 // Input must guarantee to fit in a Smi.
3779 class UnsafeSmiTagUint32 : public FixedInputValueNodeT<1, UnsafeSmiTagUint32> {
3781 
3782  public:
3783  explicit UnsafeSmiTagUint32(uint64_t bitfield) : Base(bitfield) {}
3784 
3786  static constexpr
3788 
3789  Input& input() { return Node::input(0); }
3790 
3791 #ifdef V8_COMPRESS_POINTERS
3792  void MarkTaggedInputsAsDecompressing() {
3793  // No tagged inputs.
3794  }
3795 #endif
3796 
3799  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3800 };
3801 
3802 // Input must guarantee to fit in a Smi.
3803 class UnsafeSmiTagIntPtr : public FixedInputValueNodeT<1, UnsafeSmiTagIntPtr> {
3805 
3806  public:
3807  explicit UnsafeSmiTagIntPtr(uint64_t bitfield) : Base(bitfield) {}
3808 
3810  static constexpr
3812 
3813  Input& input() { return Node::input(0); }
3814 
3815 #ifdef V8_COMPRESS_POINTERS
3816  void MarkTaggedInputsAsDecompressing() {
3817  // No tagged inputs.
3818  }
3819 #endif
3820 
3823  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3824 };
3825 
3826 class CheckedSmiUntag : public FixedInputValueNodeT<1, CheckedSmiUntag> {
3828 
3829  public:
3830  explicit CheckedSmiUntag(uint64_t bitfield) : Base(bitfield) {}
3831 
3835  static constexpr
3837 
3838  Input& input() { return Node::input(0); }
3839 
3840 #ifdef V8_COMPRESS_POINTERS
3841  void MarkTaggedInputsAsDecompressing() {
3842  // Don't need to decompress to untag.
3843  }
3844 #endif
3845 
3848  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3849 };
3850 
3851 class UnsafeSmiUntag : public FixedInputValueNodeT<1, UnsafeSmiUntag> {
3853 
3854  public:
3855  explicit UnsafeSmiUntag(uint64_t bitfield) : Base(bitfield) {}
3856 
3857  static constexpr OpProperties kProperties =
3859  static constexpr
3861 
3862  Input& input() { return Node::input(0); }
3863 
3864 #ifdef V8_COMPRESS_POINTERS
3865  void MarkTaggedInputsAsDecompressing() {
3866  // Don't need to decompress to untag.
3867  }
3868 #endif
3869 
3872  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
3873 };
3874 
3875 class Int32Constant : public FixedInputValueNodeT<0, Int32Constant> {
3877 
3878  public:
3880 
3881  explicit Int32Constant(uint64_t bitfield, int32_t value)
3882  : Base(bitfield), value_(value) {}
3883 
3885 
3886  int32_t value() const { return value_; }
3887 
3888  bool ToBoolean(LocalIsolate* local_isolate) const { return value_ != 0; }
3889 
3892  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3893 
3895  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
3896 
3897  private:
3899 };
3900 
3901 class Uint32Constant : public FixedInputValueNodeT<0, Uint32Constant> {
3903 
3904  public:
3906 
3907  explicit Uint32Constant(uint64_t bitfield, uint32_t value)
3908  : Base(bitfield), value_(value) {}
3909 
3911 
3912  uint32_t value() const { return value_; }
3913 
3914  bool ToBoolean(LocalIsolate* local_isolate) const { return value_ != 0; }
3915 
3918  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3919 
3921  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
3922 
3923  private:
3924  const uint32_t value_;
3925 };
3926 
3927 class IntPtrConstant : public FixedInputValueNodeT<0, IntPtrConstant> {
3929 
3930  public:
3932 
3933  explicit IntPtrConstant(uint64_t bitfield, intptr_t value)
3934  : Base(bitfield), value_(value) {}
3935 
3937 
3938  intptr_t value() const { return value_; }
3939 
3940  bool ToBoolean(LocalIsolate* local_isolate) const { return value_ != 0; }
3941 
3944  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3945 
3947  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
3948 
3949  private:
3950  const intptr_t value_;
3951 };
3952 
3953 class Float64Constant : public FixedInputValueNodeT<0, Float64Constant> {
3955 
3956  public:
3958 
3959  explicit Float64Constant(uint64_t bitfield, Float64 value)
3960  : Base(bitfield), value_(value) {}
3961 
3962  explicit Float64Constant(uint64_t bitfield, uint64_t bitpattern)
3963  : Base(bitfield), value_(Float64::FromBits(bitpattern)) {}
3964 
3966 
3967  Float64 value() const { return value_; }
3968 
3969  bool ToBoolean(LocalIsolate* local_isolate) const {
3970  return value_.get_scalar() != 0.0 && !value_.is_nan();
3971  }
3972 
3975  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
3976 
3978  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
3979 
3980  private:
3982 };
3983 
3985  : public FixedInputValueNodeT<1, Int32ToUint8Clamped> {
3987 
3988  public:
3989  explicit Int32ToUint8Clamped(uint64_t bitfield) : Base(bitfield) {}
3990 
3992  static constexpr
3994 
3995  Input& input() { return Node::input(0); }
3996 
3999  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4000 };
4001 
4003  : public FixedInputValueNodeT<1, Uint32ToUint8Clamped> {
4005 
4006  public:
4007  explicit Uint32ToUint8Clamped(uint64_t bitfield) : Base(bitfield) {}
4008 
4010  static constexpr
4012 
4013  Input& input() { return Node::input(0); }
4014 
4017  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4018 };
4019 
4021  : public FixedInputValueNodeT<1, Float64ToUint8Clamped> {
4023 
4024  public:
4025  explicit Float64ToUint8Clamped(uint64_t bitfield) : Base(bitfield) {}
4026 
4028  static constexpr
4030 
4031  Input& input() { return Node::input(0); }
4032 
4035  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4036 };
4037 
4039  : public FixedInputValueNodeT<1, CheckedNumberToUint8Clamped> {
4041 
4042  public:
4043  explicit CheckedNumberToUint8Clamped(uint64_t bitfield) : Base(bitfield) {}
4044 
4045  static constexpr OpProperties kProperties =
4047  static constexpr
4049 
4050  Input& input() { return Node::input(0); }
4051 
4054  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4055 };
4056 
4057 class Int32ToNumber : public FixedInputValueNodeT<1, Int32ToNumber> {
4059 
4060  public:
4061  explicit Int32ToNumber(uint64_t bitfield) : Base(bitfield) {}
4062 
4066  static constexpr
4068 
4069  Input& input() { return Node::input(0); }
4070 
4071  int MaxCallStackArgs() const { return 0; }
4074  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4075 };
4076 
4077 class Uint32ToNumber : public FixedInputValueNodeT<1, Uint32ToNumber> {
4079 
4080  public:
4081  explicit Uint32ToNumber(uint64_t bitfield) : Base(bitfield) {}
4082 
4086  static constexpr
4088 
4089  Input& input() { return Node::input(0); }
4090 
4091  int MaxCallStackArgs() const { return 0; }
4094  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4095 };
4096 
4097 class IntPtrToNumber : public FixedInputValueNodeT<1, IntPtrToNumber> {
4099 
4100  public:
4101  explicit IntPtrToNumber(uint64_t bitfield) : Base(bitfield) {}
4102 
4106  static constexpr
4108 
4109  Input& input() { return Node::input(0); }
4110 
4111  int MaxCallStackArgs() const { return 0; }
4114  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4115 };
4116 
4117 class Float64ToTagged : public FixedInputValueNodeT<1, Float64ToTagged> {
4119 
4120  public:
4122  explicit Float64ToTagged(uint64_t bitfield, ConversionMode mode)
4123  : Base(ConversionModeBitField::update(bitfield, mode)) {}
4124  static constexpr
4126 
4130 
4131  Input& input() { return Node::input(0); }
4132 
4133  int MaxCallStackArgs() const { return 0; }
4136  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4137 
4138  auto options() const { return std::tuple{conversion_mode()}; }
4139 
4141  return ConversionModeBitField::decode(bitfield());
4142  }
4143 
4144  private:
4146  return ConversionModeBitField::decode(bitfield()) ==
4148  }
4149 
4150  using ConversionModeBitField = NextBitField<ConversionMode, 1>;
4151 };
4152 
4153 // Essentially the same as Float64ToTagged but the result cannot be shared as it
4154 // will be used as a mutable heap number by a store.
4156  : public FixedInputValueNodeT<1, Float64ToHeapNumberForField> {
4158 
4159  public:
4160  explicit Float64ToHeapNumberForField(uint64_t bitfield) : Base(bitfield) {}
4161  static constexpr
4163 
4167 
4168  Input& input() { return Node::input(0); }
4169 
4170  int MaxCallStackArgs() const { return 0; }
4173  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4174 };
4175 
4177  : public FixedInputValueNodeT<1, HoleyFloat64ToTagged> {
4179 
4180  public:
4182  explicit HoleyFloat64ToTagged(uint64_t bitfield, ConversionMode mode)
4183  : Base(ConversionModeBitField::update(bitfield, mode)) {}
4184  static constexpr
4186 
4190 
4191  Input& input() { return Node::input(0); }
4192 
4193  int MaxCallStackArgs() const { return 0; }
4196  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4197 
4199  set_bitfield(ConversionModeBitField::update(bitfield(), mode));
4200  }
4201 
4202  auto options() const { return std::tuple{conversion_mode()}; }
4203 
4205  return ConversionModeBitField::decode(bitfield());
4206  }
4207 
4208  private:
4210  return ConversionModeBitField::decode(bitfield()) ==
4212  }
4213  using ConversionModeBitField = NextBitField<ConversionMode, 1>;
4214 };
4215 
4217  : public FixedInputValueNodeT<1, CheckedSmiTagFloat64> {
4219 
4220  public:
4221  explicit CheckedSmiTagFloat64(uint64_t bitfield) : Base(bitfield) {}
4222  static constexpr
4224 
4225  static constexpr OpProperties kProperties =
4227 
4228  Input& input() { return Node::input(0); }
4229 
4230  int MaxCallStackArgs() const { return 0; }
4233  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4234 };
4235 
4237  : public FixedInputValueNodeT<1, CheckedInt32ToUint32> {
4239 
4240  public:
4241  explicit CheckedInt32ToUint32(uint64_t bitfield) : Base(bitfield) {}
4242 
4246  static constexpr
4248 
4249  Input& input() { return Node::input(0); }
4250 
4253  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4254 };
4255 
4257  : public FixedInputValueNodeT<1, CheckedIntPtrToUint32> {
4259 
4260  public:
4261  explicit CheckedIntPtrToUint32(uint64_t bitfield) : Base(bitfield) {}
4262 
4266  static constexpr
4268 
4269  Input& input() { return Node::input(0); }
4270 
4273  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4274 };
4275 
4277  : public FixedInputValueNodeT<1, UnsafeInt32ToUint32> {
4279 
4280  public:
4281  explicit UnsafeInt32ToUint32(uint64_t bitfield) : Base(bitfield) {}
4282 
4283  static constexpr OpProperties kProperties =
4285  static constexpr
4287 
4288  Input& input() { return Node::input(0); }
4289 
4292  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4293 };
4294 
4296  : public FixedInputValueNodeT<1, CheckedUint32ToInt32> {
4298 
4299  public:
4300  explicit CheckedUint32ToInt32(uint64_t bitfield) : Base(bitfield) {}
4301 
4305  static constexpr
4307 
4308  Input& input() { return Node::input(0); }
4309 
4312  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4313 };
4314 
4316  : public FixedInputValueNodeT<1, CheckedIntPtrToInt32> {
4318 
4319  public:
4320  explicit CheckedIntPtrToInt32(uint64_t bitfield) : Base(bitfield) {}
4321 
4325  static constexpr
4327 
4328  Input& input() { return Node::input(0); }
4329 
4332  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4333 };
4334 
4336  : public FixedInputValueNodeT<1, ChangeInt32ToFloat64> {
4338 
4339  public:
4340  explicit ChangeInt32ToFloat64(uint64_t bitfield) : Base(bitfield) {}
4341 
4342  static constexpr OpProperties kProperties =
4344  static constexpr
4346 
4347  Input& input() { return Node::input(0); }
4348 
4351  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4352 };
4353 
4355  : public FixedInputValueNodeT<1, ChangeUint32ToFloat64> {
4357 
4358  public:
4359  explicit ChangeUint32ToFloat64(uint64_t bitfield) : Base(bitfield) {}
4360 
4361  static constexpr OpProperties kProperties =
4363  static constexpr
4365 
4366  Input& input() { return Node::input(0); }
4367 
4370  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4371 };
4372 
4374  : public FixedInputValueNodeT<1, ChangeIntPtrToFloat64> {
4376 
4377  public:
4378  explicit ChangeIntPtrToFloat64(uint64_t bitfield) : Base(bitfield) {}
4379 
4380  static constexpr OpProperties kProperties =
4382  static constexpr
4384 
4385  Input& input() { return Node::input(0); }
4386 
4389  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4390 };
4391 
4393  : public FixedInputValueNodeT<1, CheckedTruncateFloat64ToInt32> {
4395 
4396  public:
4397  explicit CheckedTruncateFloat64ToInt32(uint64_t bitfield) : Base(bitfield) {}
4398 
4402  static constexpr
4404 
4405  Input& input() { return Node::input(0); }
4406 
4409  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4410 };
4411 
4413  : public FixedInputValueNodeT<1, Int32AbsWithOverflow> {
4415 
4416  public:
4417  static constexpr OpProperties kProperties =
4419  static constexpr
4421 
4422  static constexpr int kValueIndex = 0;
4424 
4425  explicit Int32AbsWithOverflow(uint64_t bitfield) : Base(bitfield) {}
4426 
4429  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4430 };
4431 
4432 class Float64Abs : public FixedInputValueNodeT<1, Float64Abs> {
4434 
4435  public:
4436  explicit Float64Abs(uint64_t bitfield) : Base(bitfield) {}
4437 
4439  static constexpr
4441 
4442  Input& input() { return Node::input(0); }
4443 
4446  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4447 };
4448 
4450  : public FixedInputValueNodeT<1, Int32CountLeadingZeros> {
4452 
4453  public:
4454  explicit Int32CountLeadingZeros(uint64_t bitfield) : Base(bitfield) {}
4455 
4457  static constexpr
4459 
4460  Input& input() { return Node::input(0); }
4461 
4464  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4465 };
4466 
4468  : public FixedInputValueNodeT<1, SmiCountLeadingZeros> {
4470 
4471  public:
4472  explicit SmiCountLeadingZeros(uint64_t bitfield) : Base(bitfield) {}
4473 
4475 
4476  static constexpr
4478 
4479  Input& input() { return Node::input(0); }
4480 
4483  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4484 };
4485 
4487  : public FixedInputValueNodeT<1, Float64CountLeadingZeros> {
4489 
4490  public:
4491  static Builtin continuation() { return Builtin::kMathClz32Continuation; }
4492 
4493  explicit Float64CountLeadingZeros(uint64_t bitfield) : Base(bitfield) {}
4494 
4495  static constexpr
4498 
4499  Input& input() { return Node::input(0); }
4500 
4503  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4504 };
4505 
4506 class Float64Round : public FixedInputValueNodeT<1, Float64Round> {
4508 
4509  public:
4510  enum class Kind { kFloor, kCeil, kNearest };
4511 
4513  switch (kind) {
4514  case Kind::kCeil:
4515  return Builtin::kMathCeilContinuation;
4516  case Kind::kFloor:
4517  return Builtin::kMathFloorContinuation;
4518  case Kind::kNearest:
4519  return Builtin::kMathRoundContinuation;
4520  }
4521  }
4522 
4523  Float64Round(uint64_t bitfield, Kind kind) : Base(bitfield), kind_(kind) {}
4524 
4526  static constexpr
4528 
4529  Input& input() { return Node::input(0); }
4530  Kind kind() const { return kind_; }
4531 
4534  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
4535 
4536  auto options() const { return std::tuple{kind_}; }
4537 
4538  private:
4540 };
4541 
4543  : public FixedInputValueNodeT<1, CheckedTruncateFloat64ToUint32> {
4545 
4546  public:
4547  explicit CheckedTruncateFloat64ToUint32(uint64_t bitfield) : Base(bitfield) {}
4548  static constexpr
4550 
4554 
4555  Input& input() { return Node::input(0); }
4556 
4559  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4560 };
4561 
4562 #define DEFINE_TRUNCATE_NODE(name, from_repr, properties) \
4563  class name : public FixedInputValueNodeT<1, name> { \
4564  using Base = FixedInputValueNodeT<1, name>; \
4565  \
4566  public: \
4567  explicit name(uint64_t bitfield) : Base(bitfield) {} \
4568  \
4569  static constexpr OpProperties kProperties = properties; \
4570  static constexpr typename Base::InputTypes kInputTypes{ \
4571  ValueRepresentation::k##from_repr}; \
4572  \
4573  Input& input() { return Node::input(0); } \
4574  \
4575  void SetValueLocationConstraints(); \
4576  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
4577  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
4578  };
4579 
4580 DEFINE_TRUNCATE_NODE(TruncateUint32ToInt32, Uint32, OpProperties::Int32())
4581 DEFINE_TRUNCATE_NODE(TruncateFloat64ToInt32, HoleyFloat64,
4582  OpProperties::Int32())
4583 DEFINE_TRUNCATE_NODE(UnsafeTruncateUint32ToInt32, Uint32, OpProperties::Int32())
4584 DEFINE_TRUNCATE_NODE(UnsafeTruncateFloat64ToInt32, HoleyFloat64,
4585  OpProperties::Int32())
4586 
4587 #undef DEFINE_TRUNCATE_NODE
4588 
4589 template <typename Derived, ValueRepresentation FloatType>
4593  : public FixedInputValueNodeT<1, Derived> {
4594  using Base = FixedInputValueNodeT<1, Derived>;
4595  using Base::result;
4596 
4597  public:
4599  uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
4600  : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
4601  conversion_type)) {}
4602 
4603  static constexpr OpProperties kProperties =
4607  static constexpr
4608  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
4609 
4610  Input& input() { return Node::input(0); }
4611 
4612  TaggedToFloat64ConversionType conversion_type() const {
4613  return TaggedToFloat64ConversionTypeOffset::decode(Base::bitfield());
4614  }
4615 
4616  DeoptimizeReason deoptimize_reason() const {
4617  return conversion_type() == TaggedToFloat64ConversionType::kNumberOrBoolean
4618  ? DeoptimizeReason::kNotANumberOrBoolean
4619  : DeoptimizeReason::kNotANumberOrOddball;
4620  }
4621 
4622  void SetValueLocationConstraints();
4623  void GenerateCode(MaglevAssembler*, const ProcessingState&);
4624  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
4625 
4626  auto options() const { return std::tuple{conversion_type()}; }
4627 
4628  private:
4629  using TaggedToFloat64ConversionTypeOffset =
4630  Base::template NextBitField<TaggedToFloat64ConversionType, 2>;
4631 };
4632 
4635  CheckedNumberOrOddballToFloat64, ValueRepresentation::kFloat64> {
4638 
4639  public:
4641  uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
4642  : Base(bitfield, conversion_type) {}
4643 };
4644 
4646  : public FixedInputValueNodeT<1, CheckedNumberOrOddballToHoleyFloat64> {
4648 
4649  public:
4650  explicit CheckedNumberOrOddballToHoleyFloat64(uint64_t bitfield)
4651  : Base(bitfield) {}
4652 
4656  static constexpr
4658 
4659  Input& input() { return Node::input(0); }
4660 
4662  return DeoptimizeReason::kNotANumberOrOddball;
4663  }
4664 
4667  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4668 };
4669 
4671  : public FixedInputValueNodeT<1, CheckedNumberToInt32> {
4673 
4674  public:
4675  explicit CheckedNumberToInt32(uint64_t bitfield) : Base(bitfield) {}
4676 
4680  static constexpr
4682 
4683  Input& input() { return Node::input(0); }
4684 
4687  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4688 };
4689 
4691  : public FixedInputValueNodeT<1, UncheckedNumberOrOddballToFloat64> {
4693 
4694  public:
4697  : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
4698  conversion_type)) {}
4699 
4700  static constexpr OpProperties kProperties =
4702  static constexpr
4704 
4705  Input& input() { return Node::input(0); }
4706 
4709  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
4710 
4712  return TaggedToFloat64ConversionTypeOffset::decode(bitfield());
4713  }
4714 
4715  auto options() const { return std::tuple{conversion_type()}; }
4716 
4717  private:
4719  NextBitField<TaggedToFloat64ConversionType, 2>;
4720 };
4721 
4723  : public FixedInputValueNodeT<1, CheckedHoleyFloat64ToFloat64> {
4725 
4726  public:
4727  explicit CheckedHoleyFloat64ToFloat64(uint64_t bitfield) : Base(bitfield) {}
4728 
4732  static constexpr
4734 
4735  Input& input() { return Node::input(0); }
4736 
4737  int MaxCallStackArgs() const { return 0; }
4740  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4741 };
4742 
4744  : public FixedInputValueNodeT<1, HoleyFloat64ToMaybeNanFloat64> {
4746 
4747  public:
4748  explicit HoleyFloat64ToMaybeNanFloat64(uint64_t bitfield) : Base(bitfield) {}
4749 
4751  static constexpr
4753 
4754  Input& input() { return Node::input(0); }
4755 
4756  int MaxCallStackArgs() const { return 0; }
4759  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4760 };
4761 
4762 #ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
4763 class Float64ToHoleyFloat64
4764  : public FixedInputValueNodeT<1, Float64ToHoleyFloat64> {
4765  using Base = FixedInputValueNodeT<1, Float64ToHoleyFloat64>;
4766 
4767  public:
4768  explicit Float64ToHoleyFloat64(uint64_t bitfield) : Base(bitfield) {}
4769 
4770  static constexpr OpProperties kProperties =
4772  static constexpr
4773  typename Base::InputTypes kInputTypes{ValueRepresentation::kFloat64};
4774 
4775  Input& input() { return Node::input(0); }
4776 
4777  void SetValueLocationConstraints();
4778  void GenerateCode(MaglevAssembler*, const ProcessingState&);
4779  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4780 };
4781 
4782 class ConvertHoleNanToUndefinedNan
4783  : public FixedInputValueNodeT<1, ConvertHoleNanToUndefinedNan> {
4784  using Base = FixedInputValueNodeT<1, ConvertHoleNanToUndefinedNan>;
4785 
4786  public:
4787  explicit ConvertHoleNanToUndefinedNan(uint64_t bitfield) : Base(bitfield) {}
4788 
4789  static constexpr OpProperties kProperties = OpProperties::HoleyFloat64();
4790  static constexpr
4791  typename Base::InputTypes kInputTypes{ValueRepresentation::kHoleyFloat64};
4792 
4793  Input& input() { return Node::input(0); }
4794 
4795  int MaxCallStackArgs() const { return 0; }
4796  void SetValueLocationConstraints();
4797  void GenerateCode(MaglevAssembler*, const ProcessingState&);
4798  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4799 };
4800 #endif // V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
4801 
4802 class HoleyFloat64IsHole : public FixedInputValueNodeT<1, HoleyFloat64IsHole> {
4804 
4805  public:
4806  explicit HoleyFloat64IsHole(uint64_t bitfield) : Base(bitfield) {}
4807 
4808  static constexpr
4810 
4811  Input& input() { return Node::input(0); }
4812 
4815  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4816 };
4817 
4819  : public FixedInputValueNodeT<1, TruncateNumberOrOddballToInt32> {
4821 
4822  public:
4825  : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
4826  conversion_type)) {}
4827 
4829  static constexpr
4831 
4832  Input& input() { return Node::input(0); }
4833 
4836  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
4837 
4839  return TaggedToFloat64ConversionTypeOffset::decode(bitfield());
4840  }
4841 
4842  auto options() const { return std::tuple{conversion_type()}; }
4843 
4844  private:
4846  NextBitField<TaggedToFloat64ConversionType, 2>;
4847 };
4848 
4850  : public FixedInputValueNodeT<1, CheckedTruncateNumberOrOddballToInt32> {
4852 
4853  public:
4856  : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
4857  conversion_type)) {}
4858 
4859  static constexpr OpProperties kProperties =
4861  static constexpr
4863 
4864  Input& input() { return Node::input(0); }
4865 
4868  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
4869 
4871  return TaggedToFloat64ConversionTypeOffset::decode(bitfield());
4872  }
4873 
4874  auto options() const { return std::tuple{conversion_type()}; }
4875 
4876  private:
4878  NextBitField<TaggedToFloat64ConversionType, 2>;
4879 };
4880 
4881 class LogicalNot : public FixedInputValueNodeT<1, LogicalNot> {
4883 
4884  public:
4885  explicit LogicalNot(uint64_t bitfield) : Base(bitfield) {}
4886 
4887  static constexpr
4889 
4890  Input& value() { return Node::input(0); }
4891 
4894  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4895 };
4896 
4897 class SetPendingMessage : public FixedInputValueNodeT<1, SetPendingMessage> {
4899 
4900  public:
4901  explicit SetPendingMessage(uint64_t bitfield) : Base(bitfield) {}
4902 
4903  static constexpr OpProperties kProperties =
4905  static constexpr
4907 
4908  Input& value() { return Node::input(0); }
4909 
4912  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4913 };
4914 
4916 class ToBoolean : public FixedInputValueNodeT<1, ToBoolean> {
4918 
4919  public:
4920  explicit ToBoolean(uint64_t bitfield, CheckType check_type)
4921  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
4922 
4923  static constexpr
4925 
4926  Input& value() { return Node::input(0); }
4927  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
4928 
4931  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4932 
4933  auto options() const { return std::tuple{check_type()}; }
4934 
4935  private:
4936  using CheckTypeBitField = NextBitField<CheckType, 1>;
4937 };
4938 
4940  : public FixedInputValueNodeT<1, ToBooleanLogicalNot> {
4942 
4943  public:
4944  explicit ToBooleanLogicalNot(uint64_t bitfield, CheckType check_type)
4945  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
4946 
4947  static constexpr
4949 
4950  Input& value() { return Node::input(0); }
4951  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
4952 
4955  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4956 
4957  auto options() const { return std::tuple{check_type()}; }
4958 
4959  private:
4960  using CheckTypeBitField = NextBitField<CheckType, 1>;
4961 };
4962 
4963 // With StringEqualInputs::kStringsOrOddballs StringEqual allows non-string
4964 // objects which are then compared with pointer equality (they will never be
4965 // equal to a String and they're equal to each other if the pointers are equal).
4967 class StringEqual : public FixedInputValueNodeT<2, StringEqual> {
4969 
4970  public:
4971  explicit StringEqual(uint64_t bitfield, StringEqualInputs inputs)
4972  : Base(bitfield), inputs_(inputs) {}
4976 
4977  static constexpr typename Base::InputTypes kInputTypes{
4979 
4980  Input& lhs() { return Node::input(0); }
4981  Input& rhs() { return Node::input(1); }
4982 
4983  int MaxCallStackArgs() const { return 0; }
4986  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
4987 
4988  StringEqualInputs inputs() const { return inputs_; }
4989  auto options() const { return std::tuple(inputs_); }
4990 
4991  private:
4993 };
4994 
4995 class TaggedEqual : public FixedInputValueNodeT<2, TaggedEqual> {
4997 
4998  public:
4999  explicit TaggedEqual(uint64_t bitfield) : Base(bitfield) {}
5000 
5001  static constexpr typename Base::InputTypes kInputTypes{
5003 
5004  Input& lhs() { return Node::input(0); }
5005  Input& rhs() { return Node::input(1); }
5006 
5007 #ifdef V8_COMPRESS_POINTERS
5008  void MarkTaggedInputsAsDecompressing() {
5009  // Don't need to decompress to compare reference equality.
5010  }
5011 #endif
5012 
5015  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5016 };
5017 
5018 class TaggedNotEqual : public FixedInputValueNodeT<2, TaggedNotEqual> {
5020 
5021  public:
5022  explicit TaggedNotEqual(uint64_t bitfield) : Base(bitfield) {}
5023 
5024  static constexpr typename Base::InputTypes kInputTypes{
5026 
5027  Input& lhs() { return Node::input(0); }
5028  Input& rhs() { return Node::input(1); }
5029 
5030 #ifdef V8_COMPRESS_POINTERS
5031  void MarkTaggedInputsAsDecompressing() {
5032  // Don't need to decompress to compare reference equality.
5033  }
5034 #endif
5035 
5038  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5039 };
5040 
5041 class TestInstanceOf : public FixedInputValueNodeT<3, TestInstanceOf> {
5043 
5044  public:
5045  explicit TestInstanceOf(uint64_t bitfield,
5047  : Base(bitfield), feedback_(feedback) {}
5048 
5049  // The implementation currently calls runtime.
5051  static constexpr typename Base::InputTypes kInputTypes{
5054 
5055  Input& context() { return input(0); }
5056  Input& object() { return input(1); }
5057  Input& callable() { return input(2); }
5058  const compiler::FeedbackSource& feedback() const { return feedback_; }
5059 
5060  int MaxCallStackArgs() const;
5063  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5064 
5065  private:
5067 };
5068 
5069 class TestUndetectable : public FixedInputValueNodeT<1, TestUndetectable> {
5071 
5072  public:
5073  explicit TestUndetectable(uint64_t bitfield, CheckType check_type)
5074  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
5075 
5076  static constexpr
5078 
5079  Input& value() { return Node::input(0); }
5080  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
5081 
5084  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5085 
5086  auto options() const { return std::tuple{check_type()}; }
5087 
5088  private:
5089  using CheckTypeBitField = NextBitField<CheckType, 1>;
5090 };
5091 
5092 class TestTypeOf : public FixedInputValueNodeT<1, TestTypeOf> {
5094 
5095  public:
5096  explicit TestTypeOf(uint64_t bitfield,
5098  : Base(bitfield), literal_(literal) {}
5099 
5100  static constexpr
5102 
5103  Input& value() { return Node::input(0); }
5104 
5107  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5108 
5109  auto options() const { return std::tuple{literal_}; }
5110 
5112 
5113  private:
5115 };
5116 
5117 class ToName : public FixedInputValueNodeT<2, ToName> {
5119 
5120  public:
5121  explicit ToName(uint64_t bitfield) : Base(bitfield) {}
5122 
5123  // The implementation currently calls runtime.
5125  static constexpr typename Base::InputTypes kInputTypes{
5127 
5128  Input& context() { return Node::input(0); }
5129  Input& value_input() { return Node::input(1); }
5130 
5131  int MaxCallStackArgs() const;
5134  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5135 };
5136 
5137 class ToNumberOrNumeric : public FixedInputValueNodeT<1, ToNumberOrNumeric> {
5139 
5140  public:
5141  explicit ToNumberOrNumeric(uint64_t bitfield, Object::Conversion mode)
5142  : Base(bitfield), mode_(mode) {}
5143 
5144  static constexpr OpProperties kProperties =
5146  static constexpr
5148 
5149  Input& value_input() { return Node::input(0); }
5150  Object::Conversion mode() const { return mode_; }
5151 
5152  int MaxCallStackArgs() const;
5155  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5156 
5157  private:
5159 };
5160 
5161 class DeleteProperty : public FixedInputValueNodeT<3, DeleteProperty> {
5163 
5164  public:
5165  explicit DeleteProperty(uint64_t bitfield, LanguageMode mode)
5166  : Base(bitfield), mode_(mode) {}
5167 
5168  // The implementation currently calls runtime.
5170  static constexpr typename Base::InputTypes kInputTypes{
5173 
5174  Input& context() { return Node::input(0); }
5175  Input& object() { return Node::input(1); }
5176  Input& key() { return Node::input(2); }
5177 
5178  LanguageMode mode() const { return mode_; }
5179 
5180  int MaxCallStackArgs() const;
5183  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5184 
5185  private:
5187 };
5188 
5189 class GeneratorStore : public NodeT<GeneratorStore> {
5191 
5192  public:
5193  // We assume the context as fixed input.
5194  static constexpr int kContextIndex = 0;
5195  static constexpr int kGeneratorIndex = 1;
5196  static constexpr int kFixedInputCount = 2;
5197 
5198  // This ctor is used when for variable input counts.
5199  // Inputs must be initialized manually.
5200  GeneratorStore(uint64_t bitfield, ValueNode* context, ValueNode* generator,
5201  int suspend_id, int bytecode_offset)
5202  : Base(bitfield),
5205  set_input(kContextIndex, context);
5206  set_input(kGeneratorIndex, generator);
5207  }
5208 
5212 
5213  int suspend_id() const { return suspend_id_; }
5214  int bytecode_offset() const { return bytecode_offset_; }
5215 
5216  Input& context_input() { return input(kContextIndex); }
5217  Input& generator_input() { return input(kGeneratorIndex); }
5218 
5220  return input_count() - kFixedInputCount;
5221  }
5224  set_input(i + kFixedInputCount, node);
5225  }
5226 
5227  int MaxCallStackArgs() const;
5228  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
5229 
5230 #ifdef V8_COMPRESS_POINTERS
5231  void MarkTaggedInputsAsDecompressing() {
5232  // Don't need to decompress to store.
5233  }
5234 #endif
5235 
5238  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5239 
5240  private:
5241  const int suspend_id_;
5242  const int bytecode_offset_;
5243 };
5244 
5245 class TryOnStackReplacement : public FixedInputNodeT<1, TryOnStackReplacement> {
5247 
5248  public:
5249  explicit TryOnStackReplacement(uint64_t bitfield, int32_t loop_depth,
5250  FeedbackSlot feedback_slot,
5251  BytecodeOffset osr_offset,
5253  : Base(bitfield),
5254  loop_depth_(loop_depth),
5255  feedback_slot_(feedback_slot),
5256  osr_offset_(osr_offset),
5257  unit_(unit) {}
5258 
5259  static constexpr OpProperties kProperties =
5262  static constexpr
5264 
5265  Input& closure() { return Node::input(0); }
5266 
5267  const MaglevCompilationUnit* unit() const { return unit_; }
5268 
5269  int MaxCallStackArgs() const;
5272  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5273 
5274  private:
5275  // For OSR.
5280 };
5281 
5282 class ForInPrepare : public FixedInputValueNodeT<2, ForInPrepare> {
5284 
5285  public:
5286  explicit ForInPrepare(uint64_t bitfield, compiler::FeedbackSource& feedback)
5287  : Base(bitfield), feedback_(feedback) {}
5288 
5289  static constexpr OpProperties kProperties =
5291  static constexpr typename Base::InputTypes kInputTypes{
5293 
5295 
5296  Input& context() { return Node::input(0); }
5297  Input& enumerator() { return Node::input(1); }
5298 
5299  int ReturnCount() const { return 2; }
5300 
5301  int MaxCallStackArgs() const;
5304  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5305 
5306  private:
5308 };
5309 
5310 class ForInNext : public FixedInputValueNodeT<5, ForInNext> {
5312 
5313  public:
5314  explicit ForInNext(uint64_t bitfield, compiler::FeedbackSource& feedback)
5315  : Base(bitfield), feedback_(feedback) {}
5316 
5318  static constexpr typename Base::InputTypes kInputTypes{
5322 
5324 
5325  Input& context() { return Node::input(0); }
5326  Input& receiver() { return Node::input(1); }
5327  Input& cache_array() { return Node::input(2); }
5328  Input& cache_type() { return Node::input(3); }
5329  Input& cache_index() { return Node::input(4); }
5330 
5331  int MaxCallStackArgs() const;
5334  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5335 
5336  private:
5338 };
5339 
5340 class GetIterator : public FixedInputValueNodeT<2, GetIterator> {
5342 
5343  public:
5344  explicit GetIterator(uint64_t bitfield, int load_slot, int call_slot,
5346  : Base(bitfield),
5349  feedback_(feedback.object()) {}
5350 
5352  static constexpr typename Base::InputTypes kInputTypes{
5354 
5355  Input& context() { return input(0); }
5356  Input& receiver() { return input(1); }
5357 
5358  int load_slot() const { return load_slot_; }
5359  int call_slot() const { return call_slot_; }
5361 
5362  int MaxCallStackArgs() const;
5365  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5366 
5367  private:
5368  const int load_slot_;
5369  const int call_slot_;
5371 };
5372 
5374  : public FixedInputValueNodeT<0, GetSecondReturnedValue> {
5376 
5377  public:
5378  // TODO(olivf): This is needed because this instruction accesses the raw
5379  // register content. We should have tuple values instead such that we can
5380  // refer to both returned values properly.
5382  explicit GetSecondReturnedValue(uint64_t bitfield) : Base(bitfield) {}
5383 
5386  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5387 };
5388 
5389 class ToObject : public FixedInputValueNodeT<2, ToObject> {
5391 
5392  public:
5393  explicit ToObject(uint64_t bitfield, CheckType check_type)
5394  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
5395 
5396  // The implementation currently calls runtime.
5398  static constexpr typename Base::InputTypes kInputTypes{
5400 
5401  Input& context() { return Node::input(0); }
5402  Input& value_input() { return Node::input(1); }
5403  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
5404 
5405  int MaxCallStackArgs() const;
5408  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5409 
5410  private:
5411  using CheckTypeBitField = NextBitField<CheckType, 1>;
5412 };
5413 
5414 class ToString : public FixedInputValueNodeT<2, ToString> {
5416 
5417  public:
5419  explicit ToString(uint64_t bitfield, ConversionMode mode)
5420  : Base(ConversionModeBitField::update(bitfield, mode)) {}
5421 
5422  // The implementation currently calls runtime.
5424  static constexpr typename Base::InputTypes kInputTypes{
5426 
5427  Input& context() { return Node::input(0); }
5428  Input& value_input() { return Node::input(1); }
5430  return ConversionModeBitField::decode(bitfield());
5431  }
5432 
5433  int MaxCallStackArgs() const;
5436  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5437 
5438  private:
5439  using ConversionModeBitField = NextBitField<ConversionMode, 1>;
5440 };
5441 
5442 class NumberToString : public FixedInputValueNodeT<1, NumberToString> {
5444 
5445  public:
5446  explicit NumberToString(uint64_t bitfield) : Base(bitfield) {}
5447 
5451  static constexpr
5453 
5454  Input& value_input() { return Node::input(0); }
5455 
5456  int MaxCallStackArgs() const { return 0; }
5459  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5460 };
5461 
5463  : public FixedInputValueNodeT<2, GeneratorRestoreRegister> {
5465 
5466  public:
5467  explicit GeneratorRestoreRegister(uint64_t bitfield, int index)
5468  : Base(bitfield), index_(index) {}
5469 
5471  static constexpr typename Base::InputTypes kInputTypes{
5473 
5474  Input& array_input() { return input(0); }
5475  Input& stale_input() { return input(1); }
5476  int index() const { return index_; }
5477 
5480  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5481 
5482  private:
5483  const int index_;
5484 };
5485 
5486 class InitialValue : public FixedInputValueNodeT<0, InitialValue> {
5488 
5489  public:
5490  explicit InitialValue(uint64_t bitfield, interpreter::Register source);
5491 
5493  uint32_t stack_slot() const;
5494  static uint32_t stack_slot(uint32_t register_idx);
5495 
5498  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5499 
5500  auto options() const { return std::tuple{source()}; }
5501 
5502  private:
5504 };
5505 
5506 class RegisterInput : public FixedInputValueNodeT<0, RegisterInput> {
5508 
5509  public:
5510  explicit RegisterInput(uint64_t bitfield, Register input)
5511  : Base(bitfield), input_(input) {}
5512 
5513  Register input() const { return input_; }
5514 
5516 
5519  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5520 
5521  private:
5523 };
5524 
5525 class SmiConstant : public FixedInputValueNodeT<0, SmiConstant> {
5527 
5528  public:
5530 
5531  explicit SmiConstant(uint64_t bitfield, int32_t value)
5532  : Base(bitfield), value_(Smi::FromInt(value)) {
5534  }
5535 
5536  Tagged<Smi> value() const { return value_; }
5537 
5538  bool ToBoolean(LocalIsolate* local_isolate) const {
5539  return value_ != Smi::FromInt(0);
5540  }
5541 
5544  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5545 
5547  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
5548 
5549  private:
5551 };
5552 
5554  : public FixedInputValueNodeT<0, TaggedIndexConstant> {
5556 
5557  public:
5559 
5560  explicit TaggedIndexConstant(uint64_t bitfield, int value)
5561  : Base(bitfield), value_(TaggedIndex::FromIntptr(value)) {
5563  }
5564 
5565  Tagged<TaggedIndex> value() const { return value_; }
5566 
5567  bool ToBoolean(LocalIsolate* local_isolate) const { UNREACHABLE(); }
5568 
5571  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5572 
5574  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
5575 
5576  private:
5578 };
5579 
5580 class Constant : public FixedInputValueNodeT<0, Constant> {
5582 
5583  public:
5585 
5586  explicit Constant(uint64_t bitfield, compiler::HeapObjectRef object)
5587  : Base(bitfield), object_(object) {}
5588 
5589  bool ToBoolean(LocalIsolate* local_isolate) const {
5590  return Object::BooleanValue(*object_.object(), local_isolate);
5591  }
5592 
5594  return object_.IsTheHole();
5595  }
5596 
5599  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5600 
5602 
5604  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
5605 
5607 
5608  private:
5610 };
5611 
5612 class RootConstant : public FixedInputValueNodeT<0, RootConstant> {
5614 
5615  public:
5617 
5618  explicit RootConstant(uint64_t bitfield, RootIndex index)
5619  : Base(bitfield), index_(index) {}
5620 
5621  bool ToBoolean(LocalIsolate* local_isolate) const;
5622 
5623  RootIndex index() const { return index_; }
5624 
5627  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5628 
5630  Handle<Object> DoReify(LocalIsolate* isolate) const;
5631 
5632  private:
5634 };
5635 
5636 class TrustedConstant : public FixedInputValueNodeT<0, TrustedConstant> {
5638 
5639  public:
5641 
5642  explicit TrustedConstant(uint64_t bitfield, compiler::HeapObjectRef object,
5644  : Base(bitfield), object_(object), tag_(tag) {}
5645 
5647 
5648  bool ToBoolean(LocalIsolate* local_isolate) const { UNREACHABLE(); }
5649 
5652  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5653 
5655  IndirectPointerTag tag() const { return tag_; }
5656 
5658  DirectHandle<Object> DoReify(LocalIsolate* isolate) const;
5659 
5660  private:
5663 };
5664 
5665 class CreateArrayLiteral : public FixedInputValueNodeT<0, CreateArrayLiteral> {
5667 
5668  public:
5669  explicit CreateArrayLiteral(uint64_t bitfield,
5672  int flags)
5673  : Base(bitfield),
5676  flags_(flags) {}
5677 
5680  int flags() const { return flags_; }
5681 
5682  // The implementation currently calls runtime.
5683  static constexpr OpProperties kProperties =
5687 
5688  int MaxCallStackArgs() const;
5691  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5692 
5693  private:
5696  const int flags_;
5697 };
5698 
5700  : public FixedInputValueNodeT<0, CreateShallowArrayLiteral> {
5702 
5703  public:
5704  explicit CreateShallowArrayLiteral(uint64_t bitfield,
5707  int flags)
5708  : Base(bitfield),
5711  flags_(flags) {}
5712 
5715  int flags() const { return flags_; }
5716 
5717  // The implementation currently calls runtime.
5718  static constexpr OpProperties kProperties =
5720 
5721  int MaxCallStackArgs() const;
5724  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5725 
5726  private:
5729  const int flags_;
5730 };
5731 
5733  : public FixedInputValueNodeT<0, CreateObjectLiteral> {
5735 
5736  public:
5738  uint64_t bitfield,
5741  : Base(bitfield),
5744  flags_(flags) {}
5745 
5747  return boilerplate_descriptor_;
5748  }
5750  int flags() const { return flags_; }
5751 
5752  // The implementation currently calls runtime.
5753  static constexpr OpProperties kProperties =
5757 
5758  int MaxCallStackArgs() const;
5761  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5762 
5763  private:
5766  const int flags_;
5767 };
5768 
5770  : public FixedInputValueNodeT<0, CreateShallowObjectLiteral> {
5772 
5773  public:
5775  uint64_t bitfield,
5778  : Base(bitfield),
5781  flags_(flags) {}
5782 
5783  // TODO(victorgomes): We should not need a boilerplate descriptor in
5784  // CreateShallowObjectLiteral.
5786  return boilerplate_descriptor_;
5787  }
5789  int flags() const { return flags_; }
5790 
5791  // The implementation currently calls runtime.
5792  static constexpr OpProperties kProperties =
5794 
5795  int MaxCallStackArgs() const;
5798  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
5799 
5800  private:
5803  const int flags_;
5804 };
5805 
5806 // VirtualObject is a ValueNode only for convenience, it should never be added
5807 // to the Maglev graph.
5808 class VirtualObject : public FixedInputValueNodeT<0, VirtualObject> {
5810 
5811  public:
5812  enum Type : uint8_t {
5817 
5818  kLast = kConsString
5819  };
5820 
5821  friend std::ostream& operator<<(std::ostream& out, Type type) {
5822  switch (type) {
5823  case kDefault:
5824  out << "object";
5825  break;
5826  case kHeapNumber:
5827  out << "number";
5828  break;
5829  case kFixedDoubleArray:
5830  out << "double[]";
5831  break;
5832  case kConsString:
5833  out << "ConsString";
5834  break;
5835  }
5836  return out;
5837  }
5838 
5840  ValueNode* first() const { return data[0]; }
5841  ValueNode* second() const { return data[1]; }
5842  // Length and map are stored for constant folding but not actually part of
5843  // the virtual object as they are not needed to materialize the cons string.
5846  std::array<ValueNode*, 2> data;
5847  };
5848 
5849  explicit VirtualObject(uint64_t bitfield, int id,
5851  : Base(bitfield), id_(id), type_(kConsString), cons_string_(cons_string) {
5852  DCHECK(!has_static_map());
5853  }
5854 
5855  explicit VirtualObject(uint64_t bitfield, compiler::MapRef map, int id,
5856  uint32_t slot_count, ValueNode** slots)
5857  : Base(bitfield),
5858  map_(map),
5859  id_(id),
5860  type_(kDefault),
5861  slots_({slot_count, slots}) {
5863  }
5864 
5865  explicit VirtualObject(uint64_t bitfield, compiler::MapRef map, int id,
5866  Float64 number)
5867  : Base(bitfield),
5868  map_(map),
5869  id_(id),
5870  type_(kHeapNumber),
5871  number_(number) {
5873  }
5874 
5875  explicit VirtualObject(uint64_t bitfield, compiler::MapRef map, int id,
5876  uint32_t length,
5878  : Base(bitfield),
5879  map_(map),
5880  id_(id),
5882  double_array_({length, elements}) {
5884  }
5885 
5888  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
5889 
5890  constexpr bool has_static_map() const {
5891  switch (type_) {
5892  case kDefault:
5893  case kHeapNumber:
5894  case kFixedDoubleArray:
5895  return true;
5896  case kConsString:
5897  return false;
5898  }
5899  }
5900 
5903  return *map_;
5904  }
5905  Type type() const { return type_; }
5906  uint32_t id() const { return id_; }
5907 
5908  size_t size() const {
5909  switch (type_) {
5910  case kDefault:
5911  return (slot_count() + 1) * kTaggedSize;
5912  case kConsString:
5913  return sizeof(ConsString);
5914  case kHeapNumber:
5915  return sizeof(HeapNumber);
5916  case kFixedDoubleArray:
5918  }
5919  }
5920 
5921  Float64 number() const {
5923  return number_;
5924  }
5925 
5926  uint32_t double_elements_length() const {
5928  return double_array_.length;
5929  }
5930 
5933  return double_array_.values;
5934  }
5935 
5936  ValueNode* get(uint32_t offset) const {
5937  DCHECK_NE(offset, 0); // Don't try to get the map through this getter.
5939  offset -= kTaggedSize;
5940  SBXCHECK_LT(offset / kTaggedSize, slot_count());
5941  return slots_.data[offset / kTaggedSize];
5942  }
5943 
5944  void set(uint32_t offset, ValueNode* value) {
5945  DCHECK_NE(offset, 0); // Don't try to set the map through this setter.
5947  DCHECK(!IsSnapshot());
5948  // Values set here can leak to the interpreter frame state. Conversions
5949  // should be stored in known_node_aspects/NodeInfo.
5950  DCHECK(!value->properties().is_conversion());
5951  offset -= kTaggedSize;
5952  SBXCHECK_LT(offset / kTaggedSize, slot_count());
5953  slots_.data[offset / kTaggedSize] = value;
5954  }
5955 
5958  return cons_string_.length;
5959  }
5960 
5963  return cons_string_;
5964  }
5965 
5966  void ClearSlots(int last_init_slot, ValueNode* clear_value) {
5968  int last_init_index = last_init_slot / kTaggedSize;
5969  for (uint32_t i = last_init_index; i < slot_count(); i++) {
5970  slots_.data[i] = clear_value;
5971  }
5972  }
5973 
5977  }
5978 
5979  bool compatible_for_merge(const VirtualObject* other) const {
5980  if (type_ != other->type_) return false;
5981  if (allocation_ != other->allocation_) return false;
5982  // Currently, the graph builder will never change the VO map.
5983  if (has_static_map()) {
5984  if (map() != other->map()) return false;
5985  }
5986  switch (other->type_) {
5987  case kHeapNumber:
5988  case kFixedDoubleArray:
5989  case kConsString:
5990  return true;
5991  case kDefault:
5992  return slot_count() == other->slot_count();
5993  }
5994  }
5995 
5996  // VOs are snapshotted at branch points and when they are leaked to
5997  // DeoptInfos. This is because the snapshots need to preserve the original
5998  // values at the time of branching or deoptimization. While a VO is not yet
5999  // snapshotted, it can be modified freely.
6000  bool IsSnapshot() const { return snapshotted_; }
6001  void Snapshot() { snapshotted_ = true; }
6002 
6003  template <typename Function>
6004  inline void ForEachInput(Function&& callback) {
6005  switch (type_) {
6006  case kDefault:
6007  for (uint32_t i = 0; i < slot_count(); i++) {
6008  callback(slots_.data[i]);
6009  }
6010  break;
6011  case kConsString:
6012  for (ValueNode*& val : cons_string_.data) {
6013  callback(val);
6014  }
6015  break;
6016  case kHeapNumber:
6017  break;
6018  case kFixedDoubleArray:
6019  break;
6020  }
6021  }
6022 
6023  template <typename Function>
6024  inline void ForEachInput(Function&& callback) const {
6025  switch (type_) {
6026  case kDefault:
6027  for (uint32_t i = 0; i < slot_count(); i++) {
6028  callback(get_by_index(i));
6029  }
6030  break;
6031  case kConsString:
6032  for (ValueNode* val : cons_string_.data) {
6033  callback(val);
6034  }
6035  break;
6036  case kHeapNumber:
6037  break;
6038  case kFixedDoubleArray:
6039  break;
6040  }
6041  }
6042 
6043  // A runtime input is an input to the virtual object that has runtime
6044  // footprint, aka, a location.
6045  template <typename Function>
6046  inline void ForEachNestedRuntimeInput(VirtualObjectList virtual_objects,
6047  Function&& f);
6048  template <typename Function>
6049  inline void ForEachNestedRuntimeInput(VirtualObjectList virtual_objects,
6050  Function&& f) const;
6051 
6052  template <typename Function>
6053  inline std::optional<VirtualObject*> Merge(const VirtualObject* other,
6054  uint32_t new_object_id, Zone* zone,
6055  Function MergeValue) const {
6056  VirtualObject* result = Clone(new_object_id, zone, /* empty_clone */ true);
6057  DCHECK(compatible_for_merge(other));
6058  switch (type_) {
6059  // These objects are immutable and thus should never need merging.
6060  case kHeapNumber:
6061  case kFixedDoubleArray:
6062  case kConsString:
6063  UNREACHABLE();
6064  case kDefault: {
6065  for (uint32_t i = 0; i < slot_count(); i++) {
6066  if (auto success =
6067  MergeValue(get_by_index(i), other->get_by_index(i))) {
6068  result->set_by_index(i, *success);
6069  } else {
6070  return {};
6071  }
6072  }
6073  break;
6074  }
6075  }
6076  return result;
6077  }
6078 
6079  VirtualObject* Clone(uint32_t new_object_id, Zone* zone,
6080  bool empty_clone = false) const {
6082  switch (type_) {
6083  case kHeapNumber:
6084  case kFixedDoubleArray:
6085  case kConsString:
6086  UNREACHABLE();
6087  case kDefault: {
6088  ValueNode** slots = zone->AllocateArray<ValueNode*>(slot_count());
6089  result = NodeBase::New<VirtualObject>(zone, 0, map(), new_object_id,
6090  slot_count(), slots);
6091  break;
6092  }
6093  }
6094  if (empty_clone) return result;
6095 
6096  // Copy content
6097  switch (type_) {
6098  case kHeapNumber:
6099  case kFixedDoubleArray:
6100  case kConsString:
6101  UNREACHABLE();
6102  case kDefault: {
6103  for (uint32_t i = 0; i < slot_count(); i++) {
6104  result->set_by_index(i, get_by_index(i));
6105  }
6106  break;
6107  }
6108  }
6109  result->set_allocation(allocation());
6110  return result;
6111  }
6112 
6113  uint32_t slot_count() const {
6115  return slots_.count;
6116  }
6117 
6118  private:
6119  ValueNode* get_by_index(uint32_t i) const {
6121  return slots_.data[i];
6122  }
6123 
6124  void set_by_index(uint32_t i, ValueNode* value) {
6126  // Values set here can leak to the interpreter. Conversions should be stored
6127  // in known_node_aspects/NodeInfo.
6128  DCHECK(!value->properties().is_conversion());
6129  slots_.data[i] = value;
6130  }
6131 
6132  struct DoubleArray {
6133  uint32_t length;
6135  };
6136  struct ObjectFields {
6137  uint32_t count; // Does not count the map.
6138  ValueNode** data; // Does not contain the map.
6139  };
6140 
6141  compiler::OptionalMapRef map_;
6142  const int id_;
6143  Type type_; // We need to cache the type. We cannot do map comparison in some
6144  // parts of the pipeline, because we would need to dereference a
6145  // handle.
6146  bool snapshotted_ = false; // Object should not be modified anymore.
6147  union {
6152  };
6153  mutable InlinedAllocation* allocation_ = nullptr;
6154 
6155  VirtualObject* next_ = nullptr;
6157 };
6158 
6160  public:
6162 
6163  class Iterator final {
6164  public:
6165  explicit Iterator(VirtualObject* entry) : entry_(entry) {}
6166 
6168  entry_ = entry_->next_;
6169  return *this;
6170  }
6171  bool operator==(const Iterator& other) const {
6172  return entry_ == other.entry_;
6173  }
6174  bool operator!=(const Iterator& other) const {
6175  return entry_ != other.entry_;
6176  }
6179 
6180  private:
6182  };
6183 
6184  bool operator==(const VirtualObjectList& other) const {
6185  return head_ == other.head_;
6186  }
6187 
6188  void Add(VirtualObject* object) {
6189  DCHECK_NOT_NULL(object);
6190  DCHECK_NULL(object->next_);
6191  object->next_ = head_;
6192  head_ = object;
6193  }
6194 
6195  bool is_empty() const { return head_ == nullptr; }
6196 
6198  VirtualObject* result = nullptr;
6199  for (VirtualObject* vo : *this) {
6200  if (vo->allocation() == allocation) {
6201  result = vo;
6202  break;
6203  }
6204  }
6205  return result;
6206  }
6207 
6208  void Print(std::ostream& os, const char* prefix,
6209  MaglevGraphLabeller* labeller) const;
6210 
6211  // It iterates both list in reverse other of ids until a common point.
6212  template <typename Function>
6214  const VirtualObjectList& list2,
6215  Function&& f) {
6216  VirtualObject* vo1 = list1.head_;
6217  VirtualObject* vo2 = list2.head_;
6218  while (vo1 != nullptr && vo2 != nullptr && vo1 != vo2) {
6219  DCHECK_NE(vo1->id(), vo2->id());
6220  if (vo1->id() > vo2->id()) {
6221  f(vo1, list1);
6222  vo1 = vo1->next_;
6223  } else {
6224  f(vo2, list2);
6225  vo2 = vo2->next_;
6226  }
6227  }
6228  if (vo1 == vo2) return vo1;
6229  return nullptr;
6230  }
6231 
6232  void Snapshot() const {
6233  for (VirtualObject* vo : *this) {
6234  if (vo->IsSnapshot()) {
6235  // Stop processing once a snapshotted object is found, as all remaining
6236  // objects must be snapshotted.
6237  break;
6238  }
6239  vo->Snapshot();
6240  }
6242  }
6243 
6244  bool IsSnapshot() const {
6245  for (VirtualObject* vo : *this) {
6246  if (!vo->IsSnapshot()) return false;
6247  }
6248  return true;
6249  }
6250 
6251  Iterator begin() const { return Iterator(head_); }
6252  Iterator end() const { return Iterator(nullptr); }
6253 
6254  private:
6256 };
6257 
6259  kUnknown,
6260  kElided,
6261  kEscaped,
6262 };
6263 
6264 class InlinedAllocation : public FixedInputValueNodeT<1, InlinedAllocation> {
6266 
6267  public:
6269 
6270  explicit InlinedAllocation(uint64_t bitfield, VirtualObject* object)
6271  : Base(bitfield),
6272  object_(object),
6274 
6275  Input& allocation_block_input() { return input(0); }
6277 
6279  static constexpr
6281 
6284  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6285 
6286  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
6287 
6288  size_t size() const { return object_->size(); }
6289 
6290  VirtualObject* object() const { return object_; }
6291 
6292  int offset() const {
6293  DCHECK_NE(offset_, -1);
6294  return offset_;
6295  }
6296  void set_offset(int offset) { offset_ = offset; }
6297 
6299 
6300  void RemoveNonEscapingUses(int n = 1) {
6302  }
6303  void AddNonEscapingUses(int n = 1) {
6304  DCHECK(!HasBeenAnalysed());
6306  }
6307  bool IsEscaping() const {
6308  DCHECK(!HasBeenAnalysed());
6309  return use_count_ > non_escaping_use_count_;
6310  }
6311  void ForceEscaping() {
6312  DCHECK(!HasBeenAnalysed());
6314  }
6315 
6316  void SetElided() {
6319  }
6320  void SetEscaped() {
6321  // We allow transitions from elided to escaped.
6324  }
6325  bool HasBeenElided() const {
6327  DCHECK_GE(use_count_, non_escaping_use_count_);
6329  }
6330  bool HasEscaped() const {
6333  }
6334  bool HasBeenAnalysed() const {
6336  }
6337 
6338  void UpdateObject(VirtualObject* object) {
6339  DCHECK_EQ(this, object->allocation());
6340  object_ = object;
6341  }
6342 
6343 #ifdef DEBUG
6344  void set_is_returned_value_from_inline_call() {
6345  is_returned_value_from_inline_call_ = true;
6346  }
6347 
6348  bool is_returned_value_from_inline_call() const {
6349  return is_returned_value_from_inline_call_;
6350  }
6351 #endif // DEBUG
6352 
6353  private:
6357  int offset_ = -1; // Set by AllocationBlock.
6358 
6359 #ifdef DEBUG
6360  bool is_returned_value_from_inline_call_ = false;
6361 #endif // DEBUG
6362 
6364  InlinedAllocation** next() { return &next_; }
6365 
6366  friend List;
6368 };
6369 
6370 template <typename Function>
6372  VirtualObjectList virtual_objects, Function&& f) {
6373  ForEachInput([&](ValueNode*& value) {
6374  if (value->Is<Identity>()) {
6375  value = value->input(0).node();
6376  }
6377  if (IsConstantNode(value->opcode())) {
6378  // No location assigned to constants.
6379  return;
6380  }
6381  // Special nodes.
6382  switch (value->opcode()) {
6383  case Opcode::kArgumentsElements:
6384  case Opcode::kArgumentsLength:
6385  case Opcode::kRestLength:
6386  // No location assigned to these opcodes.
6387  break;
6388  case Opcode::kVirtualObject:
6389  UNREACHABLE();
6390  case Opcode::kInlinedAllocation: {
6391  InlinedAllocation* alloc = value->Cast<InlinedAllocation>();
6392  VirtualObject* inner_vobject = virtual_objects.FindAllocatedWith(alloc);
6393  // Check if it has escaped.
6394  if (inner_vobject &&
6395  (!alloc->HasBeenAnalysed() || alloc->HasBeenElided())) {
6396  inner_vobject->ForEachNestedRuntimeInput(virtual_objects, f);
6397  } else {
6398  f(value);
6399  }
6400  break;
6401  }
6402  default:
6403  f(value);
6404  break;
6405  }
6406  });
6407 }
6408 
6409 template <typename Function>
6410 inline void VirtualObject::ForEachNestedRuntimeInput(
6411  VirtualObjectList virtual_objects, Function&& f) const {
6412  ForEachInput([&](ValueNode* value) {
6413  if (value->Is<Identity>()) {
6414  value = value->input(0).node();
6415  }
6416  if (IsConstantNode(value->opcode())) {
6417  // No location assigned to constants.
6418  return;
6419  }
6420  // Special nodes.
6421  switch (value->opcode()) {
6422  case Opcode::kArgumentsElements:
6423  case Opcode::kArgumentsLength:
6424  case Opcode::kRestLength:
6425  // No location assigned to these opcodes.
6426  break;
6427  case Opcode::kVirtualObject:
6428  UNREACHABLE();
6429  case Opcode::kInlinedAllocation: {
6430  InlinedAllocation* alloc = value->Cast<InlinedAllocation>();
6431  VirtualObject* inner_vobject = virtual_objects.FindAllocatedWith(alloc);
6432  // Check if it has escaped.
6433  if (inner_vobject &&
6434  (!alloc->HasBeenAnalysed() || alloc->HasBeenElided())) {
6435  inner_vobject->ForEachNestedRuntimeInput(virtual_objects, f);
6436  } else {
6437  f(value);
6438  }
6439  break;
6440  }
6441  default:
6442  f(value);
6443  break;
6444  }
6445  });
6446 }
6447 
6448 class AllocationBlock : public FixedInputValueNodeT<0, AllocationBlock> {
6450 
6451  public:
6452  explicit AllocationBlock(uint64_t bitfield, AllocationType allocation_type)
6453  : Base(bitfield), allocation_type_(allocation_type) {}
6454 
6455  static constexpr OpProperties kProperties = OpProperties::CanAllocate() |
6456  OpProperties::DeferredCall() |
6457  OpProperties::NotIdempotent();
6458 
6459  int MaxCallStackArgs() const { return 0; }
6462  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6463 
6464  AllocationType allocation_type() const { return allocation_type_; }
6465  int size() const { return size_; }
6466  void set_size(int size) { size_ = size; }
6467 
6468  InlinedAllocation::List& allocation_list() { return allocation_list_; }
6469 
6470  void Add(InlinedAllocation* alloc) {
6471  allocation_list_.Add(alloc);
6472  size_ += alloc->size();
6473  }
6474 
6475  void TryPretenure(ValueNode* input);
6476 
6478  return elided_write_barriers_depend_on_type_;
6479  }
6481  elided_write_barriers_depend_on_type_ = true;
6482  }
6483 
6484  private:
6485  void TryPretenure();
6487  int size_ = 0;
6488  bool elided_write_barriers_depend_on_type_ = false;
6490 };
6491 
6492 class ArgumentsLength : public FixedInputValueNodeT<0, ArgumentsLength> {
6494 
6495  public:
6496  explicit ArgumentsLength(uint64_t bitfield) : Base(bitfield) {}
6497 
6498  static constexpr OpProperties kProperties = OpProperties::Int32();
6499 
6500  void SetValueLocationConstraints();
6501  void GenerateCode(MaglevAssembler*, const ProcessingState&);
6502  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
6503 };
6504 
6505 class RestLength : public FixedInputValueNodeT<0, RestLength> {
6507 
6508  public:
6509  explicit RestLength(uint64_t bitfield, int formal_parameter_count)
6510  : Base(bitfield), formal_parameter_count_(formal_parameter_count) {}
6511 
6512  void SetValueLocationConstraints();
6513  void GenerateCode(MaglevAssembler*, const ProcessingState&);
6514  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
6515 
6516  int formal_parameter_count() const { return formal_parameter_count_; }
6517 
6518  auto options() const { return std::tuple{formal_parameter_count_}; }
6519 
6520  private:
6522 };
6523 
6524 class ArgumentsElements : public FixedInputValueNodeT<1, ArgumentsElements> {
6526 
6527  public:
6528  explicit ArgumentsElements(uint64_t bitfield, CreateArgumentsType type,
6529  int formal_parameter_count)
6530  : Base(bitfield),
6531  type_(type),
6532  formal_parameter_count_(formal_parameter_count) {}
6533 
6534  static constexpr OpProperties kProperties = OpProperties::Call() |
6536  OpProperties::NotIdempotent();
6537 
6538  static constexpr
6539  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
6540 
6541  Input& arguments_count_input() { return input(0); }
6542 
6543  int MaxCallStackArgs() const { return 0; }
6546  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
6547 
6548  CreateArgumentsType type() const { return type_; }
6549  int formal_parameter_count() const { return formal_parameter_count_; }
6550 
6551  private:
6554 };
6555 
6556 // TODO(victorgomes): This node is currently not eliminated by the escape
6557 // analysis.
6559  : public FixedInputValueNodeT<1, AllocateElementsArray> {
6561 
6562  public:
6563  explicit AllocateElementsArray(uint64_t bitfield,
6564  AllocationType allocation_type)
6565  : Base(bitfield), allocation_type_(allocation_type) {}
6566 
6567  static constexpr OpProperties kProperties =
6568  OpProperties::CanAllocate() | OpProperties::EagerDeopt() |
6569  OpProperties::DeferredCall() | OpProperties::NotIdempotent();
6570 
6571  Input& length_input() { return input(0); }
6572 
6573  static constexpr
6574  typename Base::InputTypes kInputTypes{ValueRepresentation::kInt32};
6575 
6576  int MaxCallStackArgs() const { return 0; }
6579  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
6580 
6581  AllocationType allocation_type() const { return allocation_type_; }
6582 
6583  private:
6585 };
6586 
6588  : public FixedInputValueNodeT<1, CreateFunctionContext> {
6590 
6591  public:
6592  explicit CreateFunctionContext(uint64_t bitfield,
6593  compiler::ScopeInfoRef scope_info,
6594  uint32_t slot_count, ScopeType scope_type)
6595  : Base(bitfield),
6596  scope_info_(scope_info),
6597  slot_count_(slot_count),
6598  scope_type_(scope_type) {}
6599 
6600  compiler::ScopeInfoRef scope_info() const { return scope_info_; }
6601  uint32_t slot_count() const { return slot_count_; }
6602  ScopeType scope_type() const { return scope_type_; }
6603 
6604  Input& context() { return input(0); }
6605 
6606  // The implementation currently calls runtime.
6607  static constexpr OpProperties kProperties =
6608  OpProperties::Call() | OpProperties::CanAllocate() |
6609  OpProperties::LazyDeopt() | OpProperties::NotIdempotent();
6610  static constexpr
6611  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
6612 
6613  int MaxCallStackArgs() const;
6616  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6617 
6618  private:
6620  const uint32_t slot_count_;
6622 };
6623 
6624 class FastCreateClosure : public FixedInputValueNodeT<1, FastCreateClosure> {
6626 
6627  public:
6629  uint64_t bitfield, compiler::SharedFunctionInfoRef shared_function_info,
6630  compiler::FeedbackCellRef feedback_cell)
6631  : Base(bitfield),
6632  shared_function_info_(shared_function_info),
6633  feedback_cell_(feedback_cell) {}
6634 
6636  return shared_function_info_;
6637  }
6638  compiler::FeedbackCellRef feedback_cell() const { return feedback_cell_; }
6639 
6640  Input& context() { return input(0); }
6641 
6642  // The implementation currently calls runtime.
6643  static constexpr OpProperties kProperties =
6644  OpProperties::Call() | OpProperties::CanAllocate() |
6645  OpProperties::LazyDeopt() | OpProperties::NotIdempotent();
6646  static constexpr
6647  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
6648 
6649  int MaxCallStackArgs() const;
6652  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6653 
6654  private:
6657 };
6658 
6660  : public FixedInputValueNodeT<0, CreateRegExpLiteral> {
6662 
6663  public:
6664  explicit CreateRegExpLiteral(uint64_t bitfield, compiler::StringRef pattern,
6665  const compiler::FeedbackSource& feedback,
6666  int flags)
6667  : Base(bitfield), pattern_(pattern), feedback_(feedback), flags_(flags) {}
6668 
6669  compiler::StringRef pattern() { return pattern_; }
6670  compiler::FeedbackSource feedback() const { return feedback_; }
6671  int flags() const { return flags_; }
6672 
6673  // The implementation currently calls runtime.
6674  static constexpr OpProperties kProperties =
6675  OpProperties::Call() | OpProperties::CanAllocate() |
6676  OpProperties::NotIdempotent() | OpProperties::CanThrow();
6677 
6678  int MaxCallStackArgs() const;
6681  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
6682 
6683  private:
6686  const int flags_;
6687 };
6688 
6689 class CreateClosure : public FixedInputValueNodeT<1, CreateClosure> {
6691 
6692  public:
6693  explicit CreateClosure(uint64_t bitfield,
6694  compiler::SharedFunctionInfoRef shared_function_info,
6695  compiler::FeedbackCellRef feedback_cell,
6696  bool pretenured)
6697  : Base(bitfield),
6698  shared_function_info_(shared_function_info),
6699  feedback_cell_(feedback_cell),
6700  pretenured_(pretenured) {}
6701 
6703  return shared_function_info_;
6704  }
6705  compiler::FeedbackCellRef feedback_cell() const { return feedback_cell_; }
6706  bool pretenured() const { return pretenured_; }
6707 
6708  Input& context() { return input(0); }
6709 
6710  // The implementation currently calls runtime.
6711  static constexpr OpProperties kProperties = OpProperties::Call() |
6713  OpProperties::NotIdempotent();
6714  static constexpr
6715  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
6716 
6717  int MaxCallStackArgs() const;
6720  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6721 
6722  private:
6725  const bool pretenured_;
6726 };
6727 
6728 #define ASSERT_CONDITION(V) \
6729  V(Equal) \
6730  V(NotEqual) \
6731  V(LessThan) \
6732  V(LessThanEqual) \
6733  V(GreaterThan) \
6734  V(GreaterThanEqual) \
6735  V(UnsignedLessThan) \
6736  V(UnsignedLessThanEqual) \
6737  V(UnsignedGreaterThan) \
6738  V(UnsignedGreaterThanEqual)
6739 
6740 enum class AssertCondition {
6741 #define D(Name) k##Name,
6742  ASSERT_CONDITION(D)
6743 #undef D
6744 };
6745 static constexpr int kNumAssertConditions =
6746 #define D(Name) +1
6747  0 ASSERT_CONDITION(D);
6748 #undef D
6749 
6750 inline std::ostream& operator<<(std::ostream& os, const AssertCondition cond) {
6751  switch (cond) {
6752 #define CASE(Name) \
6753  case AssertCondition::k##Name: \
6754  os << #Name; \
6755  break;
6757 #undef CASE
6758  }
6759  return os;
6760 }
6761 
6762 class AssertInt32 : public FixedInputNodeT<2, AssertInt32> {
6764 
6765  public:
6766  explicit AssertInt32(uint64_t bitfield, AssertCondition condition,
6767  AbortReason reason)
6768  : Base(bitfield), condition_(condition), reason_(reason) {}
6769 
6770  static constexpr typename Base::InputTypes kInputTypes{
6771  ValueRepresentation::kInt32, ValueRepresentation::kInt32};
6772 
6773  Input& left_input() { return input(0); }
6774  Input& right_input() { return input(1); }
6775 
6778  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6779 
6780  auto options() const { return std::tuple{condition_, reason_}; }
6781 
6782  AssertCondition condition() const { return condition_; }
6783  AbortReason reason() const { return reason_; }
6784 
6785  private:
6788 };
6789 
6790 class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
6792 
6793  public:
6794  explicit CheckMaps(uint64_t bitfield, const compiler::ZoneRefSet<Map>& maps,
6795  CheckType check_type)
6796  : Base(CheckTypeBitField::update(bitfield, check_type)), maps_(maps) {}
6797  explicit CheckMaps(uint64_t bitfield,
6799  CheckType check_type, Zone* zone)
6800  : Base(CheckTypeBitField::update(bitfield, check_type)),
6801  maps_(maps.begin(), maps.end(), zone) {}
6802 
6803  static constexpr OpProperties kProperties =
6804  OpProperties::EagerDeopt() | OpProperties::CanRead();
6805  static constexpr
6806  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
6807 
6808  const compiler::ZoneRefSet<Map>& maps() const { return maps_; }
6809  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
6810 
6811  static constexpr int kReceiverIndex = 0;
6812  Input& receiver_input() { return input(kReceiverIndex); }
6813 
6816  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6817 
6818  auto options() const { return std::tuple{maps_, check_type()}; }
6819 
6820  private:
6821  using CheckTypeBitField = NextBitField<CheckType, 1>;
6823 };
6824 
6826  : public FixedInputNodeT<1, CheckMapsWithMigrationAndDeopt> {
6828 
6829  public:
6830  explicit CheckMapsWithMigrationAndDeopt(uint64_t bitfield,
6831  const compiler::ZoneRefSet<Map>& maps,
6832  CheckType check_type)
6833  : Base(CheckTypeBitField::update(bitfield, check_type)), maps_(maps) {}
6835  uint64_t bitfield, base::Vector<const compiler::MapRef> maps,
6836  CheckType check_type, Zone* zone)
6837  : Base(CheckTypeBitField::update(bitfield, check_type)),
6838  maps_(maps.begin(), maps.end(), zone) {}
6839 
6840  static constexpr OpProperties kProperties =
6841  OpProperties::EagerDeopt() | OpProperties::DeferredCall() |
6842  OpProperties::CanAllocate() | OpProperties::CanWrite() |
6843  OpProperties::CanRead();
6844 
6845  static constexpr
6846  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
6847 
6848  const compiler::ZoneRefSet<Map>& maps() const { return maps_; }
6849  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
6850 
6851  static constexpr int kReceiverIndex = 0;
6852  Input& receiver_input() { return input(kReceiverIndex); }
6853 
6854  int MaxCallStackArgs() const;
6857  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6858 
6859  auto options() const { return std::tuple{maps_, check_type()}; }
6860 
6861  private:
6862  using CheckTypeBitField = NextBitField<CheckType, 1>;
6864 };
6865 
6867  : public FixedInputNodeT<2, CheckMapsWithAlreadyLoadedMap> {
6869 
6870  public:
6871  explicit CheckMapsWithAlreadyLoadedMap(uint64_t bitfield,
6872  const compiler::ZoneRefSet<Map>& maps)
6873  : Base(bitfield), maps_(maps) {}
6875  uint64_t bitfield, base::Vector<const compiler::MapRef> maps, Zone* zone)
6876  : Base(bitfield), maps_(maps.begin(), maps.end(), zone) {}
6877 
6878  static constexpr OpProperties kProperties =
6879  OpProperties::EagerDeopt() | OpProperties::CanRead();
6880  static constexpr typename Base::InputTypes kInputTypes{
6881  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
6882 
6883  const compiler::ZoneRefSet<Map>& maps() const { return maps_; }
6884 
6885  Input& object_input() { return input(0); }
6886  Input& map_input() { return input(1); }
6887 
6890  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6891 
6892  auto options() const { return std::tuple{maps_}; }
6893 
6894  private:
6896 };
6897 
6898 class CheckValue : public FixedInputNodeT<1, CheckValue> {
6900 
6901  public:
6902  explicit CheckValue(uint64_t bitfield, const compiler::HeapObjectRef value,
6903  DeoptimizeReason reason)
6904  : Base(bitfield | ReasonField::encode(reason)), value_(value) {}
6905 
6906  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
6907  static constexpr
6908  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
6909 
6910  compiler::HeapObjectRef value() const { return value_; }
6911 
6912  static constexpr int kTargetIndex = 0;
6913  Input& target_input() { return input(kTargetIndex); }
6914 
6915 #ifdef V8_COMPRESS_POINTERS
6916  void MarkTaggedInputsAsDecompressing() {
6917  // Don't need to decompress to compare reference equality.
6918  }
6919 #endif
6920 
6923  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6924 
6925  auto options() const { return std::tuple{value_, deoptimize_reason()}; }
6926 
6928 
6929  private:
6931 };
6932 
6933 class CheckValueEqualsInt32 : public FixedInputNodeT<1, CheckValueEqualsInt32> {
6935 
6936  public:
6937  explicit CheckValueEqualsInt32(uint64_t bitfield, int32_t value,
6938  DeoptimizeReason reason)
6939  : Base(bitfield | ReasonField::encode(reason)), value_(value) {}
6940 
6941  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
6942  static constexpr
6943  typename Base::InputTypes kInputTypes{ValueRepresentation::kInt32};
6944 
6945  int32_t value() const { return value_; }
6946 
6947  static constexpr int kTargetIndex = 0;
6948  Input& target_input() { return input(kTargetIndex); }
6949 
6952  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6953 
6954  auto options() const { return std::tuple{value_, deoptimize_reason()}; }
6955 
6957 
6958  private:
6960 };
6961 
6962 class CheckFloat64SameValue : public FixedInputNodeT<1, CheckFloat64SameValue> {
6964 
6965  public:
6966  explicit CheckFloat64SameValue(uint64_t bitfield, Float64 value,
6967  DeoptimizeReason reason)
6968  : Base(bitfield | ReasonField::encode(reason)), value_(value) {}
6969 
6970  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
6971  static constexpr
6972  typename Base::InputTypes kInputTypes{ValueRepresentation::kFloat64};
6973 
6974  Float64 value() const { return value_; }
6975 
6976  static constexpr int kTargetIndex = 0;
6977  Input& target_input() { return input(kTargetIndex); }
6978 
6979  void SetValueLocationConstraints();
6980  void GenerateCode(MaglevAssembler*, const ProcessingState&);
6981  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
6982 
6983  auto options() const { return std::tuple{value_, deoptimize_reason()}; }
6984 
6986 
6987  private:
6989 };
6990 
6992  : public FixedInputNodeT<1, CheckValueEqualsString> {
6994 
6995  public:
6996  explicit CheckValueEqualsString(uint64_t bitfield,
6998  DeoptimizeReason reason)
6999  : Base(bitfield | ReasonField::encode(reason)), value_(value) {}
7000 
7001  // Can allocate if strings are flattened for comparison.
7002  static constexpr OpProperties kProperties = OpProperties::CanAllocate() |
7003  OpProperties::EagerDeopt() |
7004  OpProperties::DeferredCall();
7005  static constexpr
7006  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7007 
7008  compiler::InternalizedStringRef value() const { return value_; }
7009 
7010  static constexpr int kTargetIndex = 0;
7011  Input& target_input() { return input(kTargetIndex); }
7012 
7013  int MaxCallStackArgs() const { return 0; }
7016  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
7017 
7018  auto options() const { return std::tuple{value_, deoptimize_reason()}; }
7019 
7021 
7022  private:
7024 };
7025 
7026 class CheckDynamicValue : public FixedInputNodeT<2, CheckDynamicValue> {
7028 
7029  public:
7030  explicit CheckDynamicValue(uint64_t bitfield, DeoptimizeReason reason)
7031  : Base(bitfield | ReasonField::encode(reason)) {}
7032 
7033  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7034  static constexpr typename Base::InputTypes kInputTypes{
7035  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
7036 
7037  static constexpr int kFirstIndex = 0;
7038  static constexpr int kSecondIndex = 1;
7039  Input& first_input() { return input(kFirstIndex); }
7040  Input& second_input() { return input(kSecondIndex); }
7041 
7042 #ifdef V8_COMPRESS_POINTERS
7043  void MarkTaggedInputsAsDecompressing() {
7044  // Don't need to decompress to compare reference equality.
7045  }
7046 #endif
7047 
7050  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
7051 
7052  auto options() const { return std::tuple{deoptimize_reason()}; }
7053 
7055 };
7056 
7057 class CheckSmi : public FixedInputNodeT<1, CheckSmi> {
7059 
7060  public:
7061  explicit CheckSmi(uint64_t bitfield) : Base(bitfield) {}
7062 
7063  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7064  static constexpr
7065  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7066 
7067  static constexpr int kReceiverIndex = 0;
7068  Input& receiver_input() { return input(kReceiverIndex); }
7069 
7070  using Node::set_input;
7071 
7072 #ifdef V8_COMPRESS_POINTERS
7073  void MarkTaggedInputsAsDecompressing() {
7074  // Don't need to decompress to check Smi bits.
7075  }
7076 #endif
7077 
7080  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7081 };
7082 
7083 class CheckNumber : public FixedInputNodeT<1, CheckNumber> {
7085 
7086  public:
7087  explicit CheckNumber(uint64_t bitfield, Object::Conversion mode)
7088  : Base(bitfield), mode_(mode) {}
7089 
7090  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7091  static constexpr
7092  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7093 
7094  static constexpr int kReceiverIndex = 0;
7095  Input& receiver_input() { return input(kReceiverIndex); }
7096  Object::Conversion mode() const { return mode_; }
7097 
7100  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7101 
7102  auto options() const { return std::tuple{mode_}; }
7103 
7104  private:
7106 };
7107 
7108 class CheckHeapObject : public FixedInputNodeT<1, CheckHeapObject> {
7110 
7111  public:
7112  explicit CheckHeapObject(uint64_t bitfield) : Base(bitfield) {}
7113 
7114  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7115  static constexpr
7116  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7117 
7118  static constexpr int kReceiverIndex = 0;
7119  Input& receiver_input() { return input(kReceiverIndex); }
7120 
7121 #ifdef V8_COMPRESS_POINTERS
7122  void MarkTaggedInputsAsDecompressing() {
7123  // Don't need to decompress to check Smi bits.
7124  }
7125 #endif
7126 
7129  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7130 };
7131 
7132 class CheckSymbol : public FixedInputNodeT<1, CheckSymbol> {
7134 
7135  public:
7136  explicit CheckSymbol(uint64_t bitfield, CheckType check_type)
7137  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
7138 
7139  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7140  static constexpr
7141  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7142 
7143  static constexpr int kReceiverIndex = 0;
7144  Input& receiver_input() { return input(kReceiverIndex); }
7145  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7146 
7149  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7150 
7151  auto options() const { return std::tuple{check_type()}; }
7152 
7153  private:
7154  using CheckTypeBitField = NextBitField<CheckType, 1>;
7155 };
7156 
7157 class CheckInstanceType : public FixedInputNodeT<1, CheckInstanceType> {
7159 
7160  public:
7161  explicit CheckInstanceType(uint64_t bitfield, CheckType check_type,
7162  const InstanceType first_instance_type,
7163  const InstanceType last_instance_type)
7164  : Base(CheckTypeBitField::update(bitfield, check_type)),
7165  first_instance_type_(first_instance_type),
7166  last_instance_type_(last_instance_type) {
7167  DCHECK_LE(first_instance_type, last_instance_type);
7168  }
7169 
7170  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7171  static constexpr
7172  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7173 
7174  static constexpr int kReceiverIndex = 0;
7175  Input& receiver_input() { return input(kReceiverIndex); }
7176 
7177  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7178 
7181  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
7182 
7183  auto options() const {
7184  return std::tuple{check_type(), first_instance_type_, last_instance_type_};
7185  }
7186 
7187  InstanceType first_instance_type() const { return first_instance_type_; }
7188  InstanceType last_instance_type() const { return last_instance_type_; }
7189 
7190  private:
7191  using CheckTypeBitField = NextBitField<CheckType, 1>;
7194 };
7195 
7196 class CheckString : public FixedInputNodeT<1, CheckString> {
7198 
7199  public:
7200  explicit CheckString(uint64_t bitfield, CheckType check_type)
7201  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
7202 
7203  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7204  static constexpr
7205  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7206 
7207  static constexpr int kReceiverIndex = 0;
7208  Input& receiver_input() { return input(kReceiverIndex); }
7209  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7210 
7213  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7214 
7215  auto options() const { return std::tuple{check_type()}; }
7216 
7217  private:
7218  using CheckTypeBitField = NextBitField<CheckType, 1>;
7219 };
7220 
7221 class CheckSeqOneByteString : public FixedInputNodeT<1, CheckSeqOneByteString> {
7223 
7224  public:
7225  explicit CheckSeqOneByteString(uint64_t bitfield, CheckType check_type)
7226  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
7227 
7228  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7229  static constexpr
7230  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7231 
7232  static constexpr int kReceiverIndex = 0;
7233  Input& receiver_input() { return input(kReceiverIndex); }
7234  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7235 
7238  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7239 
7240  auto options() const { return std::tuple{check_type()}; }
7241 
7242  private:
7243  using CheckTypeBitField = NextBitField<CheckType, 1>;
7244 };
7245 
7247  : public FixedInputNodeT<1, CheckStringOrStringWrapper> {
7249 
7250  public:
7251  explicit CheckStringOrStringWrapper(uint64_t bitfield, CheckType check_type)
7252  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
7253 
7254  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7255  static constexpr
7256  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7257 
7258  static constexpr int kReceiverIndex = 0;
7259  Input& receiver_input() { return input(kReceiverIndex); }
7260  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7261 
7264  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7265 
7266  auto options() const { return std::tuple{check_type()}; }
7267 
7268  private:
7269  using CheckTypeBitField = NextBitField<CheckType, 1>;
7270 };
7271 
7272 class CheckStringOrOddball : public FixedInputNodeT<1, CheckStringOrOddball> {
7274 
7275  public:
7276  explicit CheckStringOrOddball(uint64_t bitfield, CheckType check_type)
7277  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
7278 
7279  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7280  static constexpr
7281  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7282 
7283  static constexpr int kReceiverIndex = 0;
7284  Input& receiver_input() { return input(kReceiverIndex); }
7285  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7286 
7289  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7290 
7291  auto options() const { return std::tuple{check_type()}; }
7292 
7293  private:
7294  using CheckTypeBitField = NextBitField<CheckType, 1>;
7295 };
7296 
7298  : public FixedInputNodeT<1, CheckDetectableCallable> {
7300 
7301  public:
7302  explicit CheckDetectableCallable(uint64_t bitfield, CheckType check_type)
7303  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
7304 
7305  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7306  static constexpr
7307  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7308 
7309  static constexpr int kReceiverIndex = 0;
7310  Input& receiver_input() { return input(kReceiverIndex); }
7311  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7312 
7315  void PrintParams(std::ostream& out, MaglevGraphLabeller*) const {}
7316 
7317  auto options() const { return std::tuple{check_type()}; }
7318 
7319  private:
7320  using CheckTypeBitField = NextBitField<CheckType, 1>;
7321 };
7322 
7324  : public FixedInputNodeT<1, CheckMapsWithMigration> {
7326 
7327  public:
7328  explicit CheckMapsWithMigration(uint64_t bitfield,
7329  const compiler::ZoneRefSet<Map>& maps,
7330  CheckType check_type)
7331  : Base(CheckTypeBitField::update(bitfield, check_type)), maps_(maps) {}
7332 
7333  static constexpr OpProperties kProperties =
7334  OpProperties::EagerDeopt() | OpProperties::DeferredCall() |
7335  OpProperties::CanAllocate() | OpProperties::CanWrite() |
7336  OpProperties::CanRead();
7337  static constexpr
7338  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7339 
7340  const compiler::ZoneRefSet<Map>& maps() const { return maps_; }
7341 
7342  static constexpr int kReceiverIndex = 0;
7343  Input& receiver_input() { return input(kReceiverIndex); }
7344  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7345 
7346  int MaxCallStackArgs() const;
7349  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
7350 
7351  void ClearUnstableNodeAspects(KnownNodeAspects& known_node_aspects);
7352 
7353  private:
7354  using CheckTypeBitField = NextBitField<CheckType, 1>;
7356 };
7357 
7358 class MigrateMapIfNeeded : public FixedInputValueNodeT<2, MigrateMapIfNeeded> {
7360 
7361  public:
7362  explicit MigrateMapIfNeeded(uint64_t bitfield) : Base(bitfield) {}
7363 
7364  static constexpr OpProperties kProperties =
7365  OpProperties::EagerDeopt() | OpProperties::DeferredCall() |
7366  OpProperties::CanAllocate() | OpProperties::CanWrite() |
7367  OpProperties::CanRead();
7368 
7369  static constexpr typename Base::InputTypes kInputTypes{
7370  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
7371 
7372  static constexpr int kMapIndex = 0;
7373  static constexpr int kObjectIndex = 1;
7374 
7375  Input& object_input() { return input(kObjectIndex); }
7376  Input& map_input() { return input(kMapIndex); }
7377 
7378  int MaxCallStackArgs() const;
7381  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7382 
7383  void ClearUnstableNodeAspects(KnownNodeAspects& known_node_aspects);
7384 };
7385 
7387  : public FixedInputNodeT<2, CheckCacheIndicesNotCleared> {
7389 
7390  public:
7391  explicit CheckCacheIndicesNotCleared(uint64_t bitfield) : Base(bitfield) {}
7392  static constexpr OpProperties kProperties =
7393  OpProperties::EagerDeopt() | OpProperties::CanRead();
7394  static constexpr typename Base::InputTypes kInputTypes{
7395  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
7396 
7397  static constexpr int kEnumIndices = 0;
7398  Input& indices_input() { return input(kEnumIndices); }
7399  static constexpr int kCacheLength = 1;
7400  Input& length_input() { return input(kCacheLength); }
7401 
7404  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7405 };
7406 
7407 class CheckJSDataViewBounds : public FixedInputNodeT<2, CheckJSDataViewBounds> {
7409 
7410  public:
7411  explicit CheckJSDataViewBounds(uint64_t bitfield,
7412  ExternalArrayType element_type)
7413  : Base(bitfield), element_type_(element_type) {}
7414 
7415  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7416  static constexpr typename Base::InputTypes kInputTypes{
7417  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
7418 
7419  static constexpr int kReceiverIndex = 0;
7420  static constexpr int kIndexIndex = 1;
7421  Input& receiver_input() { return input(kReceiverIndex); }
7422  Input& index_input() { return input(kIndexIndex); }
7423 
7424  int MaxCallStackArgs() const;
7425  void SetValueLocationConstraints();
7426  void GenerateCode(MaglevAssembler*, const ProcessingState&);
7427  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7428 
7429  auto options() const { return std::tuple{element_type_}; }
7430 
7431  ExternalArrayType element_type() const { return element_type_; }
7432 
7433  private:
7435 };
7436 
7438  : public FixedInputValueNodeT<1, LoadTypedArrayLength> {
7440 
7441  public:
7442  explicit LoadTypedArrayLength(uint64_t bitfield, ElementsKind elements_kind)
7443  : Base(bitfield), elements_kind_(elements_kind) {}
7444  static constexpr OpProperties kProperties =
7445  OpProperties::IntPtr() | OpProperties::CanRead();
7446  static constexpr
7447  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7448 
7449  static constexpr int kReceiverIndex = 0;
7450  Input& receiver_input() { return input(kReceiverIndex); }
7451 
7452  void SetValueLocationConstraints();
7453  void GenerateCode(MaglevAssembler*, const ProcessingState&);
7454  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7455 
7456  auto options() const { return std::tuple{elements_kind_}; }
7457 
7458  ElementsKind elements_kind() const { return elements_kind_; }
7459 
7460  private:
7462 };
7463 
7465  : public FixedInputNodeT<1, CheckTypedArrayNotDetached> {
7467 
7468  public:
7469  explicit CheckTypedArrayNotDetached(uint64_t bitfield) : Base(bitfield) {}
7470  static constexpr OpProperties kProperties =
7471  OpProperties::EagerDeopt() | OpProperties::CanRead();
7472  static constexpr
7473  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7474 
7475  static constexpr int kObjectIndex = 0;
7476  Input& object_input() { return input(kObjectIndex); }
7477 
7480  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7481 };
7482 
7483 class CheckTypedArrayBounds : public FixedInputNodeT<2, CheckTypedArrayBounds> {
7485 
7486  public:
7487  explicit CheckTypedArrayBounds(uint64_t bitfield) : Base(bitfield) {}
7488  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7489  static constexpr typename Base::InputTypes kInputTypes{
7490  ValueRepresentation::kUint32, ValueRepresentation::kIntPtr};
7491 
7492  static constexpr int kIndexIndex = 0;
7493  static constexpr int kLengthIndex = 1;
7494  Input& index_input() { return input(kIndexIndex); }
7495  Input& length_input() { return input(kLengthIndex); }
7496 
7499  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7500 };
7501 
7502 class CheckInt32Condition : public FixedInputNodeT<2, CheckInt32Condition> {
7504 
7505  public:
7506  explicit CheckInt32Condition(uint64_t bitfield, AssertCondition condition,
7507  DeoptimizeReason reason)
7508  : Base(bitfield | ConditionField::encode(condition) |
7509  ReasonField::encode(reason)) {}
7510 
7511  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
7512  static constexpr typename Base::InputTypes kInputTypes{
7513  ValueRepresentation::kInt32, ValueRepresentation::kInt32};
7514 
7515  static constexpr int kLeftIndex = 0;
7516  static constexpr int kRightIndex = 1;
7517  Input& left_input() { return input(kLeftIndex); }
7518  Input& right_input() { return input(kRightIndex); }
7519 
7521  return ConditionField::decode(bitfield());
7522  }
7523 
7526  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
7527 
7528  auto options() const { return std::tuple{condition(), deoptimize_reason()}; }
7529 
7531 
7532  private:
7534  ReasonField::Next<AssertCondition, base::bits::WhichPowerOfTwo<size_t>(
7535  base::bits::RoundUpToPowerOfTwo32(
7537 };
7538 
7539 class DebugBreak : public FixedInputNodeT<0, DebugBreak> {
7541 
7542  public:
7543  explicit DebugBreak(uint64_t bitfield) : Base(bitfield) {}
7544 
7545  static constexpr OpProperties kProperties = OpProperties::NotIdempotent();
7546 
7549  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7550 };
7551 
7552 class Dead : public NodeT<Dead> {
7554 
7555  public:
7558  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7561 
7562  private:
7563  explicit Dead(uint64_t bitfield) : Base(bitfield) {}
7564 };
7565 
7567  : public FixedInputNodeT<0, FunctionEntryStackCheck> {
7569 
7570  public:
7571  explicit FunctionEntryStackCheck(uint64_t bitfield) : Base(bitfield) {}
7572 
7573  // Although FunctionEntryStackCheck calls a builtin, we don't mark it as Call
7574  // here. The register allocator should not spill any live registers, since the
7575  // builtin already handles it. The only possible live register is
7576  // kJavaScriptCallNewTargetRegister.
7577  static constexpr OpProperties kProperties =
7578  OpProperties::LazyDeopt() | OpProperties::CanAllocate() |
7579  OpProperties::DeferredCall() | OpProperties::NotIdempotent();
7580 
7581  int MaxCallStackArgs() const;
7584  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7585 };
7586 
7588  : public FixedInputValueNodeT<1, CheckedInternalizedString> {
7590 
7591  public:
7592  explicit CheckedInternalizedString(uint64_t bitfield, CheckType check_type)
7593  : Base(CheckTypeBitField::update(bitfield, check_type)) {
7594  CHECK_EQ(properties().value_representation(), ValueRepresentation::kTagged);
7595  }
7596 
7597  static constexpr OpProperties kProperties =
7598  OpProperties::EagerDeopt() | OpProperties::TaggedValue();
7599  static constexpr
7600  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7601 
7602  static constexpr int kObjectIndex = 0;
7603  Input& object_input() { return Node::input(kObjectIndex); }
7604  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7605 
7608  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7609 
7610  auto options() const { return std::tuple{check_type()}; }
7611 
7612  private:
7613  using CheckTypeBitField = NextBitField<CheckType, 1>;
7614 };
7615 
7617  : public FixedInputValueNodeT<1, CheckedObjectToIndex> {
7619 
7620  public:
7621  explicit CheckedObjectToIndex(uint64_t bitfield, CheckType check_type)
7622  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
7623 
7624  static constexpr OpProperties kProperties =
7625  OpProperties::EagerDeopt() | OpProperties::Int32() |
7626  OpProperties::DeferredCall() | OpProperties::ConversionNode();
7627  static constexpr
7628  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7629 
7630  static constexpr int kObjectIndex = 0;
7631  Input& object_input() { return Node::input(kObjectIndex); }
7632  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
7633 
7634  int MaxCallStackArgs() const;
7637  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7638 
7639  auto options() const { return std::tuple{check_type()}; }
7640 
7641  private:
7642  using CheckTypeBitField = NextBitField<CheckType, 1>;
7643 };
7644 
7645 class GetTemplateObject : public FixedInputValueNodeT<1, GetTemplateObject> {
7647 
7648  public:
7650  uint64_t bitfield, compiler::SharedFunctionInfoRef shared_function_info,
7651  const compiler::FeedbackSource& feedback)
7652  : Base(bitfield),
7653  shared_function_info_(shared_function_info),
7654  feedback_(feedback) {}
7655 
7656  // The implementation currently calls runtime.
7657  static constexpr OpProperties kProperties =
7658  OpProperties::GenericRuntimeOrBuiltinCall();
7659  static constexpr
7660  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7661 
7662  Input& description() { return input(0); }
7663 
7665  return shared_function_info_;
7666  }
7667  compiler::FeedbackSource feedback() const { return feedback_; }
7668 
7669  int MaxCallStackArgs() const;
7672  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7673 
7674  private:
7677 };
7678 
7680  : public FixedInputValueNodeT<1, HasInPrototypeChain> {
7682 
7683  public:
7684  explicit HasInPrototypeChain(uint64_t bitfield,
7686  : Base(bitfield), prototype_(prototype) {}
7687 
7688  // The implementation can enter user code in the deferred call (due to
7689  // proxied getPrototypeOf).
7690  static constexpr OpProperties kProperties =
7691  OpProperties::DeferredCall() | OpProperties::CanCallUserCode();
7692  static constexpr
7693  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
7694 
7695  Input& object() { return input(0); }
7696 
7697  compiler::HeapObjectRef prototype() { return prototype_; }
7698 
7699  int MaxCallStackArgs() const;
7702  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
7703 
7704  private:
7706 };
7707 
7709  : public FixedInputValueNodeT<1, BuiltinStringFromCharCode> {
7711 
7712  public:
7713  explicit BuiltinStringFromCharCode(uint64_t bitfield) : Base(bitfield) {}
7714 
7715  static constexpr OpProperties kProperties =
7716  OpProperties::CanAllocate() | OpProperties::DeferredCall();
7717  static constexpr
7718  typename Base::InputTypes kInputTypes{ValueRepresentation::kInt32};
7719 
7720  Input& code_input() { return input(0); }
7721 
7722  int MaxCallStackArgs() const;
7723  void SetValueLocationConstraints();
7724  void GenerateCode(MaglevAssembler*, const ProcessingState&);
7725  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7726 };
7727 
7729  : public FixedInputValueNodeT<2,
7730  BuiltinStringPrototypeCharCodeOrCodePointAt> {
7731  using Base =
7733 
7734  public:
7735  enum Mode {
7738  };
7739 
7741  Mode mode)
7742  : Base(bitfield | ModeField::encode(mode)) {}
7743 
7744  static constexpr OpProperties kProperties =
7745  OpProperties::CanAllocate() | OpProperties::CanRead() |
7746  OpProperties::DeferredCall() | OpProperties::Int32();
7747  static constexpr typename Base::InputTypes kInputTypes{
7748  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
7749 
7750  static constexpr int kStringIndex = 0;
7751  static constexpr int kIndexIndex = 1;
7752  Input& string_input() { return input(kStringIndex); }
7753  Input& index_input() { return input(kIndexIndex); }
7754 
7755  int MaxCallStackArgs() const;
7758  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
7759 
7760  auto options() const { return std::tuple{mode()}; }
7761 
7762  Mode mode() const { return ModeField::decode(bitfield()); }
7763 
7764  private:
7765  using ModeField = NextBitField<Mode, 1>;
7766 };
7767 
7769  : public FixedInputValueNodeT<2, BuiltinSeqOneByteStringCharCodeAt> {
7771 
7772  public:
7773  explicit BuiltinSeqOneByteStringCharCodeAt(uint64_t bitfield)
7774  : Base(bitfield) {}
7775 
7776  static constexpr OpProperties kProperties =
7777  OpProperties::CanRead() | OpProperties::Int32();
7778  static constexpr typename Base::InputTypes kInputTypes{
7779  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
7780 
7781  static constexpr int kStringIndex = 0;
7782  static constexpr int kIndexIndex = 1;
7783  Input& string_input() { return input(kStringIndex); }
7784  Input& index_input() { return input(kIndexIndex); }
7785 
7788  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7789 };
7790 
7791 class MapPrototypeGet : public FixedInputValueNodeT<2, MapPrototypeGet> {
7793 
7794  public:
7795  explicit MapPrototypeGet(uint64_t bitfield) : Base(bitfield) {}
7796 
7797  static constexpr OpProperties kProperties =
7798  OpProperties::Call() | OpProperties::CanAllocate() |
7799  OpProperties::CanRead() | OpProperties::TaggedValue();
7800  static constexpr typename Base::InputTypes kInputTypes{
7801  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
7802 
7803  Input& table_input() { return input(0); }
7804  Input& key_input() { return input(1); }
7805 
7806  int MaxCallStackArgs() const {
7807  // Only implemented in Turbolev.
7808  UNREACHABLE();
7809  }
7810 
7813  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7814 };
7815 
7817  : public FixedInputValueNodeT<2, MapPrototypeGetInt32Key> {
7819 
7820  public:
7821  explicit MapPrototypeGetInt32Key(uint64_t bitfield) : Base(bitfield) {}
7822 
7823  static constexpr OpProperties kProperties = OpProperties::CanAllocate() |
7824  OpProperties::CanRead() |
7825  OpProperties::TaggedValue();
7826  static constexpr typename Base::InputTypes kInputTypes{
7827  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
7828 
7829  Input& table_input() { return input(0); }
7830  Input& key_input() { return input(1); }
7831 
7834  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7835 };
7836 
7837 class SetPrototypeHas : public FixedInputValueNodeT<2, SetPrototypeHas> {
7839 
7840  public:
7841  explicit SetPrototypeHas(uint64_t bitfield) : Base(bitfield) {}
7842 
7843  // CanAllocate is needed, since finding strings in hash tables does an
7844  // equality comparison which flattens strings.
7845  static constexpr OpProperties kProperties =
7846  OpProperties::Call() | OpProperties::CanAllocate() |
7847  OpProperties::CanRead() | OpProperties::TaggedValue();
7848  static constexpr typename Base::InputTypes kInputTypes{
7849  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
7850 
7851  Input& table_input() { return input(0); }
7852  Input& key_input() { return input(1); }
7853 
7854  int MaxCallStackArgs() const {
7855  // Only implemented in Turbolev.
7856  UNREACHABLE();
7857  }
7858 
7861  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7862 };
7863 
7865  : public FixedInputValueNodeT<1, CreateFastArrayElements> {
7867 
7868  public:
7869  explicit CreateFastArrayElements(uint64_t bitfield,
7870  AllocationType allocation_type)
7871  : Base(bitfield), allocation_type_(allocation_type) {}
7872 
7873  AllocationType allocation_type() const { return allocation_type_; }
7874 
7875  static constexpr OpProperties kProperties =
7876  OpProperties::CanAllocate() | OpProperties::NotIdempotent();
7877 
7878  static constexpr
7879  typename Base::InputTypes kInputTypes{ValueRepresentation::kInt32};
7880 
7881  Input& length_input() { return input(0); }
7882 
7885  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7886 
7887  private:
7889 };
7890 
7892  : public FixedInputValueNodeT<3, TransitionAndStoreArrayElement> {
7894 
7895  public:
7896  explicit TransitionAndStoreArrayElement(uint64_t bitfield,
7897  const compiler::MapRef& fast_map,
7898  const compiler::MapRef& double_map)
7899  : Base(bitfield), fast_map_(fast_map), double_map_(double_map) {}
7900 
7901  static constexpr OpProperties kProperties =
7902  OpProperties::AnySideEffects() | OpProperties::DeferredCall();
7903  static constexpr typename Base::InputTypes kInputTypes{
7904  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
7905  ValueRepresentation::kTagged};
7906 
7907  Input& array_input() { return input(0); }
7908  Input& index_input() { return input(1); }
7909  Input& value_input() { return input(2); }
7910 
7911  compiler::MapRef fast_map() const { return fast_map_; }
7912  compiler::MapRef double_map() const { return double_map_; }
7913 
7914  int MaxCallStackArgs() const {
7915  // Only implemented in Turbolev.
7916  UNREACHABLE();
7917  }
7920 
7921  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
7922 
7923  private:
7926 };
7927 
7929  public:
7930  enum Kind {
7937  };
7938 
7940  const ZoneVector<compiler::MapRef>& maps) {
7942  }
7944  const ZoneVector<compiler::MapRef>& maps, compiler::ObjectRef constant) {
7945  return PolymorphicAccessInfo(kConstant, maps, Representation::Tagged(),
7946  constant);
7947  }
7949  const ZoneVector<compiler::MapRef>& maps, Float64 constant) {
7950  return PolymorphicAccessInfo(kConstantDouble, maps, constant);
7951  }
7953  const ZoneVector<compiler::MapRef>& maps, Representation representation,
7954  compiler::OptionalJSObjectRef holder, FieldIndex field_index) {
7955  return PolymorphicAccessInfo(kDataLoad, maps, representation, holder,
7956  field_index);
7957  }
7959  const ZoneVector<compiler::MapRef>& maps, compiler::CellRef cell) {
7960  return PolymorphicAccessInfo(kModuleExport, maps, Representation::Tagged(),
7961  cell);
7962  }
7964  const ZoneVector<compiler::MapRef>& maps) {
7965  return PolymorphicAccessInfo(kStringLength, maps, Representation::Smi());
7966  }
7967 
7968  Kind kind() const { return kind_; }
7969 
7970  const ZoneVector<compiler::MapRef>& maps() const { return maps_; }
7971 
7973  DCHECK_EQ(kind_, kConstant);
7974  return constant_.object();
7975  }
7976 
7977  double constant_double() const {
7978  DCHECK_EQ(kind_, kConstantDouble);
7979  return constant_double_.get_scalar();
7980  }
7981 
7983  DCHECK_EQ(kind_, kModuleExport);
7984  return constant_.AsCell().object();
7985  }
7986 
7987  compiler::OptionalJSObjectRef holder() const {
7988  DCHECK_EQ(kind_, kDataLoad);
7989  return data_load_.holder_;
7990  }
7991 
7993  DCHECK_EQ(kind_, kDataLoad);
7994  return data_load_.field_index_;
7995  }
7996 
7997  Representation field_representation() const { return representation_; }
7998 
7999  bool operator==(const PolymorphicAccessInfo& other) const {
8000  if (kind_ != other.kind_ || !(representation_ == other.representation_)) {
8001  return false;
8002  }
8003  if (maps_.size() != other.maps_.size()) {
8004  return false;
8005  }
8006  for (size_t i = 0; i < maps_.size(); ++i) {
8007  if (maps_[i] != other.maps_[i]) {
8008  return false;
8009  }
8010  }
8011  switch (kind_) {
8012  case kNotFound:
8013  case kStringLength:
8014  return true;
8015  case kModuleExport:
8016  case kConstant:
8017  return constant_.equals(other.constant_);
8018  case kConstantDouble:
8019  return constant_double_ == other.constant_double_;
8020  case kDataLoad:
8021  return data_load_.holder_.equals(other.data_load_.holder_) &&
8022  data_load_.field_index_ == other.data_load_.field_index_;
8023  }
8024  }
8025 
8026  size_t hash_value() const {
8027  size_t hash = base::hash_value(kind_);
8028  hash = base::hash_combine(hash, base::hash_value(representation_.kind()));
8029  for (auto map : maps()) {
8030  hash = base::hash_combine(hash, map.hash_value());
8031  }
8032  switch (kind_) {
8033  case kNotFound:
8034  case kStringLength:
8035  break;
8036  case kModuleExport:
8037  case kConstant:
8038  hash = base::hash_combine(hash, constant_.hash_value());
8039  break;
8040  case kConstantDouble:
8041  hash = base::hash_combine(hash, base::hash_value(constant_double_));
8042  break;
8043  case kDataLoad:
8044  hash = base::hash_combine(
8045  hash, base::hash_value(data_load_.holder_.hash_value()));
8046  hash = base::hash_combine(
8047  hash, base::hash_value(data_load_.field_index_.index()));
8048  break;
8049  }
8050  return hash;
8051  }
8052 
8053  private:
8055  const ZoneVector<compiler::MapRef>& maps,
8056  Representation representation)
8057  : kind_(kind), maps_(maps), representation_(representation) {
8058  DCHECK(kind == kNotFound || kind == kStringLength);
8059  }
8060 
8062  Representation representation,
8063  compiler::ObjectRef constant)
8064  : kind_(kind),
8065  maps_(maps),
8066  representation_(representation),
8067  constant_(constant) {
8068  DCHECK(kind == kConstant || kind == kModuleExport);
8069  }
8070 
8072  Float64 constant)
8073  : kind_(kind),
8074  maps_(maps),
8075  representation_(Representation::Double()),
8076  constant_double_(constant) {
8077  DCHECK_EQ(kind, kConstantDouble);
8078  }
8079 
8081  Representation representation,
8082  compiler::OptionalJSObjectRef holder,
8083  FieldIndex field_index)
8084  : kind_(kind),
8085  maps_(maps),
8086  representation_(representation),
8087  data_load_{holder, field_index} {
8088  DCHECK_EQ(kind, kDataLoad);
8089  }
8090 
8091  const Kind kind_;
8092  // TODO(victorgomes): Create a PolymorphicMapChecks and avoid the maps here.
8095  union {
8096  const compiler::ObjectRef constant_;
8098  struct {
8099  const compiler::OptionalJSObjectRef holder_;
8101  } data_load_;
8102  };
8103 };
8104 
8105 template <typename Derived = LoadTaggedField>
8106 class AbstractLoadTaggedField : public FixedInputValueNodeT<1, Derived> {
8108  using Base::result;
8109 
8110  public:
8111  explicit AbstractLoadTaggedField(uint64_t bitfield, const int offset)
8112  : Base(bitfield), offset_(offset) {}
8113 
8114  static constexpr OpProperties kProperties = OpProperties::CanRead();
8115  static constexpr
8116  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
8117 
8118  int offset() const { return offset_; }
8119 
8120  using Base::input;
8121  static constexpr int kObjectIndex = 0;
8122  Input& object_input() { return input(kObjectIndex); }
8123 
8126  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8127 
8128  auto options() const { return std::tuple{offset()}; }
8129 
8130  using Base::decompresses_tagged_result;
8131 
8132  private:
8133  const int offset_;
8134 };
8135 
8136 class LoadTaggedField : public AbstractLoadTaggedField<LoadTaggedField> {
8138 
8139  public:
8140  explicit LoadTaggedField(uint64_t bitfield, const int offset)
8141  : Base(bitfield, offset) {}
8142 };
8143 
8145  : public AbstractLoadTaggedField<LoadTaggedFieldForProperty> {
8147 
8148  public:
8149  explicit LoadTaggedFieldForProperty(uint64_t bitfield, const int offset,
8151  : Base(bitfield, offset), name_(name) {}
8152  compiler::NameRef name() { return name_; }
8153 
8154  auto options() const { return std::tuple{offset(), name_}; }
8155 
8156  private:
8158 };
8159 
8161  : public AbstractLoadTaggedField<LoadTaggedFieldForContextSlotNoCells> {
8163 
8164  public:
8165  explicit LoadTaggedFieldForContextSlotNoCells(uint64_t bitfield,
8166  const int offset)
8167  : Base(bitfield, offset) {}
8168 };
8169 
8171  : public FixedInputValueNodeT<1, LoadTaggedFieldForContextSlot> {
8173 
8174  public:
8175  explicit LoadTaggedFieldForContextSlot(uint64_t bitfield, const int offset)
8176  : Base(bitfield), offset_(offset) {}
8177 
8178  static constexpr OpProperties kProperties = OpProperties::CanRead() |
8180  OpProperties::DeferredCall();
8181  static constexpr
8182  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
8183 
8184  int offset() const { return offset_; }
8185 
8186  using Base::input;
8187  static constexpr int kContextIndex = 0;
8188  Input& context() { return input(kContextIndex); }
8189 
8190  int MaxCallStackArgs() const { return 0; }
8193  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8194 
8195  auto options() const { return std::tuple{offset()}; }
8196 
8197  using Base::decompresses_tagged_result;
8198 
8199  private:
8200  const int offset_;
8201 };
8202 
8203 class LoadDoubleField : public FixedInputValueNodeT<1, LoadDoubleField> {
8205 
8206  public:
8207  explicit LoadDoubleField(uint64_t bitfield, int offset)
8208  : Base(bitfield), offset_(offset) {}
8209 
8210  static constexpr OpProperties kProperties =
8211  OpProperties::CanRead() | OpProperties::Float64();
8212  static constexpr
8213  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
8214 
8215  int offset() const { return offset_; }
8216 
8217  static constexpr int kObjectIndex = 0;
8218  Input& object_input() { return input(kObjectIndex); }
8219 
8222  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8223 
8224  auto options() const { return std::tuple{offset()}; }
8225 
8226  private:
8227  const int offset_;
8228 };
8229 
8230 class LoadFloat64 : public FixedInputValueNodeT<1, LoadFloat64> {
8232 
8233  public:
8234  explicit LoadFloat64(uint64_t bitfield, int offset)
8235  : Base(bitfield), offset_(offset) {}
8236 
8237  static constexpr OpProperties kProperties =
8238  OpProperties::CanRead() | OpProperties::Float64();
8239  static constexpr
8240  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
8241 
8242  int offset() const { return offset_; }
8243 
8244  static constexpr int kObjectIndex = 0;
8245  Input& object_input() { return input(kObjectIndex); }
8246 
8249  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8250 
8251  auto options() const { return std::tuple{offset()}; }
8252 
8253  private:
8254  const int offset_;
8255 };
8256 
8257 class LoadInt32 : public FixedInputValueNodeT<1, LoadInt32> {
8259 
8260  public:
8261  explicit LoadInt32(uint64_t bitfield, int offset)
8262  : Base(bitfield), offset_(offset) {}
8263 
8264  static constexpr OpProperties kProperties =
8265  OpProperties::CanRead() | OpProperties::Int32();
8266  static constexpr
8267  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
8268 
8269  int offset() const { return offset_; }
8270 
8271  static constexpr int kObjectIndex = 0;
8272  Input& object_input() { return input(kObjectIndex); }
8273 
8276  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8277 
8278  auto options() const { return std::tuple{offset()}; }
8279 
8280  private:
8281  const int offset_;
8282 };
8283 
8285  : public FixedInputValueNodeT<2, LoadTaggedFieldByFieldIndex> {
8287 
8288  public:
8289  explicit LoadTaggedFieldByFieldIndex(uint64_t bitfield) : Base(bitfield) {}
8290 
8291  static constexpr OpProperties kProperties = OpProperties::CanAllocate() |
8292  OpProperties::CanRead() |
8293  OpProperties::DeferredCall();
8294  static constexpr typename Base::InputTypes kInputTypes{
8295  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
8296 
8297  static constexpr int kObjectIndex = 0;
8298  static constexpr int kIndexIndex = 1;
8299  Input& object_input() { return input(kObjectIndex); }
8300  Input& index_input() { return input(kIndexIndex); }
8301 
8302 #ifdef V8_COMPRESS_POINTERS
8303  void MarkTaggedInputsAsDecompressing() {
8304  // Only need to decompress the object, the index should be a Smi.
8305  object_input().node()->SetTaggedResultNeedsDecompress();
8306  }
8307 #endif
8308 
8309  int MaxCallStackArgs() const { return 0; }
8312  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8313 };
8314 
8316  : public FixedInputValueNodeT<2, LoadFixedArrayElement> {
8318 
8319  public:
8320  explicit LoadFixedArrayElement(uint64_t bitfield) : Base(bitfield) {}
8321 
8322  static constexpr OpProperties kProperties = OpProperties::CanRead();
8323  static constexpr typename Base::InputTypes kInputTypes{
8324  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
8325 
8326  static constexpr int kElementsIndex = 0;
8327  static constexpr int kIndexIndex = 1;
8328  Input& elements_input() { return input(kElementsIndex); }
8329  Input& index_input() { return input(kIndexIndex); }
8330 
8333  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8334 };
8335 
8337  : public FixedInputValueNodeT<2, EnsureWritableFastElements> {
8339 
8340  public:
8341  explicit EnsureWritableFastElements(uint64_t bitfield) : Base(bitfield) {}
8342 
8343  static constexpr OpProperties kProperties = OpProperties::CanAllocate() |
8344  OpProperties::DeferredCall() |
8345  OpProperties::CanWrite();
8346  static constexpr typename Base::InputTypes kInputTypes{
8347  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
8348 
8349  static constexpr int kElementsIndex = 0;
8350  static constexpr int kObjectIndex = 1;
8351  Input& elements_input() { return input(kElementsIndex); }
8352  Input& object_input() { return input(kObjectIndex); }
8353 
8354  int MaxCallStackArgs() const { return 0; }
8357  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8358 };
8359 
8361  : public FixedInputValueNodeT<2, ExtendPropertiesBackingStore> {
8363 
8364  public:
8365  explicit ExtendPropertiesBackingStore(uint64_t bitfield, int old_length)
8366  : Base(bitfield), old_length_(old_length) {}
8367 
8368  static constexpr OpProperties kProperties =
8369  OpProperties::CanAllocate() | OpProperties::CanRead() |
8370  OpProperties::CanWrite() | OpProperties::DeferredCall() |
8371  OpProperties::EagerDeopt() | OpProperties::NotIdempotent();
8372 
8373  static constexpr typename Base::InputTypes kInputTypes{
8374  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
8375 
8376  static constexpr int kPropertyArrayIndex = 0;
8377  static constexpr int kObjectIndex = 1;
8378  Input& property_array_input() { return input(kPropertyArrayIndex); }
8379  Input& object_input() { return input(kObjectIndex); }
8380 
8381  int MaxCallStackArgs() const { return 0; }
8384  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8385 
8386  int old_length() const { return old_length_; }
8387 
8388  private:
8389  const int old_length_;
8390 };
8391 
8393  : public FixedInputValueNodeT<4, MaybeGrowFastElements> {
8395 
8396  public:
8397  explicit MaybeGrowFastElements(uint64_t bitfield, ElementsKind elements_kind)
8398  : Base(bitfield), elements_kind_(elements_kind) {}
8399 
8400  static constexpr OpProperties kProperties =
8401  OpProperties::CanAllocate() | OpProperties::DeferredCall() |
8402  OpProperties::CanWrite() | OpProperties::EagerDeopt();
8403  static constexpr typename Base::InputTypes kInputTypes{
8404  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
8405  ValueRepresentation::kInt32, ValueRepresentation::kInt32};
8406 
8407  static constexpr int kElementsIndex = 0;
8408  static constexpr int kObjectIndex = 1;
8409  static constexpr int kIndexIndex = 2;
8410  static constexpr int kElementsLengthIndex = 3;
8411  Input& elements_input() { return input(kElementsIndex); }
8412  Input& object_input() { return input(kObjectIndex); }
8413  Input& index_input() { return input(kIndexIndex); }
8414  Input& elements_length_input() { return input(kElementsLengthIndex); }
8415 
8416  ElementsKind elements_kind() const { return elements_kind_; }
8417 
8418  int MaxCallStackArgs() const { return 0; }
8421  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8422 
8423  auto options() const { return std::tuple{elements_kind()}; }
8424 
8425  private:
8427 };
8428 
8430  : public FixedInputNodeT<3, StoreFixedArrayElementWithWriteBarrier> {
8432 
8433  public:
8434  explicit StoreFixedArrayElementWithWriteBarrier(uint64_t bitfield)
8435  : Base(bitfield) {}
8436 
8437  static constexpr OpProperties kProperties =
8438  OpProperties::CanWrite() | OpProperties::DeferredCall();
8439  static constexpr typename Base::InputTypes kInputTypes{
8440  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
8441  ValueRepresentation::kTagged};
8442 
8443  static constexpr int kElementsIndex = 0;
8444  static constexpr int kIndexIndex = 1;
8445  static constexpr int kValueIndex = 2;
8446  Input& elements_input() { return input(kElementsIndex); }
8447  Input& index_input() { return input(kIndexIndex); }
8448  Input& value_input() { return input(kValueIndex); }
8449 
8450  int MaxCallStackArgs() const { return 0; }
8453  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8454 };
8455 
8456 // StoreFixedArrayElementNoWriteBarrier never does a Deferred Call. However,
8457 // PhiRepresentationSelector can cause some StoreFixedArrayElementNoWriteBarrier
8458 // to become StoreFixedArrayElementWithWriteBarrier, which can do Deferred
8459 // Calls, and thus need the register snapshot. We thus set the DeferredCall
8460 // property in StoreFixedArrayElementNoWriteBarrier so that it's allocated with
8461 // enough space for the register snapshot.
8463  : public FixedInputNodeT<3, StoreFixedArrayElementNoWriteBarrier> {
8465 
8466  public:
8467  explicit StoreFixedArrayElementNoWriteBarrier(uint64_t bitfield)
8468  : Base(bitfield) {}
8469 
8470  static constexpr OpProperties kProperties =
8471  OpProperties::CanWrite() | OpProperties::DeferredCall();
8472  static constexpr typename Base::InputTypes kInputTypes{
8473  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
8474  ValueRepresentation::kTagged};
8475 
8476  static constexpr int kElementsIndex = 0;
8477  static constexpr int kIndexIndex = 1;
8478  static constexpr int kValueIndex = 2;
8479  Input& elements_input() { return input(kElementsIndex); }
8480  Input& index_input() { return input(kIndexIndex); }
8481  Input& value_input() { return input(kValueIndex); }
8482 
8483  int MaxCallStackArgs() const {
8484  // StoreFixedArrayElementNoWriteBarrier never really does any call.
8485  return 0;
8486  }
8489  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8490 };
8491 
8493  : public FixedInputValueNodeT<2, LoadFixedDoubleArrayElement> {
8495 
8496  public:
8497  explicit LoadFixedDoubleArrayElement(uint64_t bitfield) : Base(bitfield) {}
8498 
8499  static constexpr OpProperties kProperties =
8500  OpProperties::CanRead() | OpProperties::Float64();
8501  static constexpr typename Base::InputTypes kInputTypes{
8502  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
8503 
8504  static constexpr int kElementsIndex = 0;
8505  static constexpr int kIndexIndex = 1;
8506  Input& elements_input() { return input(kElementsIndex); }
8507  Input& index_input() { return input(kIndexIndex); }
8508 
8511  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8512 };
8513 
8515  : public FixedInputValueNodeT<2, LoadHoleyFixedDoubleArrayElement> {
8517 
8518  public:
8519  explicit LoadHoleyFixedDoubleArrayElement(uint64_t bitfield)
8520  : Base(bitfield) {}
8521 
8522  static constexpr OpProperties kProperties =
8523  OpProperties::CanRead() | OpProperties::HoleyFloat64();
8524  static constexpr typename Base::InputTypes kInputTypes{
8525  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
8526 
8527  static constexpr int kElementsIndex = 0;
8528  static constexpr int kIndexIndex = 1;
8529  Input& elements_input() { return input(kElementsIndex); }
8530  Input& index_input() { return input(kIndexIndex); }
8531 
8534  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8535 };
8536 
8538  : public FixedInputValueNodeT<
8539  2, LoadHoleyFixedDoubleArrayElementCheckedNotHole> {
8540  using Base =
8542 
8543  public:
8545  : Base(bitfield) {}
8546 
8547  static constexpr OpProperties kProperties = OpProperties::CanRead() |
8549  OpProperties::EagerDeopt();
8550  static constexpr typename Base::InputTypes kInputTypes{
8551  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
8552 
8553  static constexpr int kElementsIndex = 0;
8554  static constexpr int kIndexIndex = 1;
8555  Input& elements_input() { return input(kElementsIndex); }
8556  Input& index_input() { return input(kIndexIndex); }
8557 
8560  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8561 };
8562 
8564  : public FixedInputNodeT<3, StoreFixedDoubleArrayElement> {
8566 
8567  public:
8568  explicit StoreFixedDoubleArrayElement(uint64_t bitfield) : Base(bitfield) {}
8569 
8570  static constexpr OpProperties kProperties = OpProperties::CanWrite();
8571  static constexpr typename Base::InputTypes kInputTypes{
8572  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
8573  ValueRepresentation::kHoleyFloat64};
8574 
8575  static constexpr int kElementsIndex = 0;
8576  static constexpr int kIndexIndex = 1;
8577  static constexpr int kValueIndex = 2;
8578  Input& elements_input() { return input(kElementsIndex); }
8579  Input& index_input() { return input(kIndexIndex); }
8580  Input& value_input() { return input(kValueIndex); }
8581 
8584  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8585 };
8586 
8588  : public FixedInputValueNodeT<3, LoadSignedIntDataViewElement> {
8590 
8591  public:
8592  explicit LoadSignedIntDataViewElement(uint64_t bitfield,
8594  : Base(bitfield), type_(type) {
8598  }
8599 
8600  static constexpr OpProperties kProperties =
8601  OpProperties::CanRead() | OpProperties::Int32();
8602  static constexpr typename Base::InputTypes kInputTypes{
8603  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
8604  ValueRepresentation::kTagged};
8605 
8606  static constexpr int kObjectIndex = 0;
8607  static constexpr int kIndexIndex = 1;
8608  static constexpr int kIsLittleEndianIndex = 2;
8609  Input& object_input() { return input(kObjectIndex); }
8610  Input& index_input() { return input(kIndexIndex); }
8611  Input& is_little_endian_input() { return input(kIsLittleEndianIndex); }
8612 
8614  return IsConstantNode(is_little_endian_input().node()->opcode());
8615  }
8616 
8619  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8620 
8621  auto options() const { return std::tuple{type_}; }
8622 
8623  ExternalArrayType type() const { return type_; }
8624 
8625  private:
8627 };
8628 
8630  : public FixedInputValueNodeT<3, LoadDoubleDataViewElement> {
8632  static constexpr ExternalArrayType type_ =
8634 
8635  public:
8636  explicit LoadDoubleDataViewElement(uint64_t bitfield, ExternalArrayType type)
8637  : Base(bitfield) {
8638  DCHECK_EQ(type, type_);
8639  }
8640 
8641  static constexpr OpProperties kProperties =
8642  OpProperties::CanRead() | OpProperties::Float64();
8643  static constexpr typename Base::InputTypes kInputTypes{
8644  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
8645  ValueRepresentation::kTagged};
8646 
8647  static constexpr int kObjectIndex = 0;
8648  static constexpr int kIndexIndex = 1;
8649  static constexpr int kIsLittleEndianIndex = 2;
8650  Input& object_input() { return input(kObjectIndex); }
8651  Input& index_input() { return input(kIndexIndex); }
8652  Input& is_little_endian_input() { return input(kIsLittleEndianIndex); }
8653 
8655  return IsConstantNode(is_little_endian_input().node()->opcode());
8656  }
8657 
8660  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8661 
8662  auto options() const { return std::tuple{type_}; }
8663 };
8664 
8665 #define LOAD_TYPED_ARRAY(name, properties, ...) \
8666  class name : public FixedInputValueNodeT<2, name> { \
8667  using Base = FixedInputValueNodeT<2, name>; \
8668  \
8669  public: \
8670  explicit name(uint64_t bitfield, ElementsKind elements_kind) \
8671  : Base(bitfield), elements_kind_(elements_kind) { \
8672  DCHECK(elements_kind == \
8673  v8::internal::compiler::turboshaft::any_of(__VA_ARGS__)); \
8674  } \
8675  \
8676  static constexpr OpProperties kProperties = \
8677  OpProperties::CanRead() | properties; \
8678  static constexpr typename Base::InputTypes kInputTypes{ \
8679  ValueRepresentation::kTagged, ValueRepresentation::kUint32}; \
8680  \
8681  static constexpr int kObjectIndex = 0; \
8682  static constexpr int kIndexIndex = 1; \
8683  Input& object_input() { return input(kObjectIndex); } \
8684  Input& index_input() { return input(kIndexIndex); } \
8685  \
8686  void SetValueLocationConstraints(); \
8687  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
8688  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
8689  \
8690  auto options() const { return std::tuple{elements_kind_}; } \
8691  \
8692  ElementsKind elements_kind() const { return elements_kind_; } \
8693  \
8694  private: \
8695  ElementsKind elements_kind_; \
8696  };
8697 
8698 LOAD_TYPED_ARRAY(LoadSignedIntTypedArrayElement, OpProperties::Int32(),
8699  INT8_ELEMENTS, INT16_ELEMENTS, INT32_ELEMENTS)
8700 
8701 LOAD_TYPED_ARRAY(LoadUnsignedIntTypedArrayElement, OpProperties::Uint32(),
8703  UINT16_ELEMENTS, UINT32_ELEMENTS)
8704 
8705 LOAD_TYPED_ARRAY(LoadDoubleTypedArrayElement, OpProperties::Float64(),
8706  FLOAT32_ELEMENTS, FLOAT64_ELEMENTS)
8707 
8708 #undef LOAD_TYPED_ARRAY
8709 
8710 #define LOAD_CONSTANT_TYPED_ARRAY(name, properties, ...) \
8711  class name : public FixedInputValueNodeT<1, name> { \
8712  using Base = FixedInputValueNodeT<1, name>; \
8713  \
8714  public: \
8715  explicit name(uint64_t bitfield, compiler::JSTypedArrayRef typed_array, \
8716  ElementsKind elements_kind) \
8717  : Base(bitfield), \
8718  typed_array_(typed_array), \
8719  elements_kind_(elements_kind) { \
8720  DCHECK(elements_kind == \
8721  v8::internal::compiler::turboshaft::any_of(__VA_ARGS__)); \
8722  } \
8723  \
8724  static constexpr OpProperties kProperties = \
8725  OpProperties::CanRead() | properties; \
8726  static constexpr \
8727  typename Base::InputTypes kInputTypes{ValueRepresentation::kUint32}; \
8728  \
8729  static constexpr int kIndexIndex = 0; \
8730  Input& index_input() { return input(kIndexIndex); } \
8731  \
8732  void SetValueLocationConstraints(); \
8733  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
8734  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
8735  \
8736  auto options() const { return std::tuple{typed_array_, elements_kind_}; } \
8737  \
8738  ElementsKind elements_kind() const { return elements_kind_; } \
8739  compiler::JSTypedArrayRef typed_array() const { return typed_array_; } \
8740  \
8741  private: \
8742  compiler::JSTypedArrayRef typed_array_; \
8743  ElementsKind elements_kind_; \
8744  };
8745 
8746 LOAD_CONSTANT_TYPED_ARRAY(LoadSignedIntConstantTypedArrayElement,
8747  OpProperties::Int32(), INT8_ELEMENTS, INT16_ELEMENTS,
8748  INT32_ELEMENTS)
8749 
8750 LOAD_CONSTANT_TYPED_ARRAY(LoadUnsignedIntConstantTypedArrayElement,
8753  UINT16_ELEMENTS, UINT32_ELEMENTS)
8754 
8755 LOAD_CONSTANT_TYPED_ARRAY(LoadDoubleConstantTypedArrayElement,
8757  FLOAT64_ELEMENTS)
8758 
8759 #undef LOAD_CONSTANT_TYPED_ARRAY
8760 
8761 #define STORE_TYPED_ARRAY(name, properties, type, ...) \
8762  class name : public FixedInputNodeT<3, name> { \
8763  using Base = FixedInputNodeT<3, name>; \
8764  \
8765  public: \
8766  explicit name(uint64_t bitfield, ElementsKind elements_kind) \
8767  : Base(bitfield), elements_kind_(elements_kind) { \
8768  DCHECK(elements_kind == \
8769  v8::internal::compiler::turboshaft::any_of(__VA_ARGS__)); \
8770  } \
8771  \
8772  static constexpr OpProperties kProperties = properties; \
8773  static constexpr typename Base::InputTypes kInputTypes{ \
8774  ValueRepresentation::kTagged, ValueRepresentation::kUint32, type}; \
8775  \
8776  static constexpr int kObjectIndex = 0; \
8777  static constexpr int kIndexIndex = 1; \
8778  static constexpr int kValueIndex = 2; \
8779  Input& object_input() { return input(kObjectIndex); } \
8780  Input& index_input() { return input(kIndexIndex); } \
8781  Input& value_input() { return input(kValueIndex); } \
8782  \
8783  void SetValueLocationConstraints(); \
8784  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
8785  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
8786  \
8787  ElementsKind elements_kind() const { return elements_kind_; } \
8788  \
8789  private: \
8790  ElementsKind elements_kind_; \
8791  };
8792 
8793 STORE_TYPED_ARRAY(StoreIntTypedArrayElement, OpProperties::CanWrite(),
8794  ValueRepresentation::kInt32, INT8_ELEMENTS, INT16_ELEMENTS,
8795  INT32_ELEMENTS, UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS,
8796  UINT16_ELEMENTS, UINT16_ELEMENTS, UINT32_ELEMENTS)
8797 STORE_TYPED_ARRAY(StoreDoubleTypedArrayElement, OpProperties::CanWrite(),
8798  ValueRepresentation::kHoleyFloat64, FLOAT32_ELEMENTS,
8799  FLOAT64_ELEMENTS)
8800 #undef STORE_TYPED_ARRAY
8801 
8802 #define STORE_CONSTANT_TYPED_ARRAY(name, properties, type, ...) \
8803  class name : public FixedInputNodeT<2, name> { \
8804  using Base = FixedInputNodeT<2, name>; \
8805  \
8806  public: \
8807  explicit name(uint64_t bitfield, compiler::JSTypedArrayRef typed_array, \
8808  ElementsKind elements_kind) \
8809  : Base(bitfield), \
8810  typed_array_(typed_array), \
8811  elements_kind_(elements_kind) { \
8812  DCHECK(elements_kind == \
8813  v8::internal::compiler::turboshaft::any_of(__VA_ARGS__)); \
8814  } \
8815  \
8816  static constexpr OpProperties kProperties = properties; \
8817  static constexpr typename Base::InputTypes kInputTypes{ \
8818  ValueRepresentation::kUint32, type}; \
8819  \
8820  static constexpr int kIndexIndex = 0; \
8821  static constexpr int kValueIndex = 1; \
8822  Input& index_input() { return input(kIndexIndex); } \
8823  Input& value_input() { return input(kValueIndex); } \
8824  \
8825  void SetValueLocationConstraints(); \
8826  void GenerateCode(MaglevAssembler*, const ProcessingState&); \
8827  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
8828  \
8829  ElementsKind elements_kind() const { return elements_kind_; } \
8830  compiler::JSTypedArrayRef typed_array() const { return typed_array_; } \
8831  \
8832  private: \
8833  compiler::JSTypedArrayRef typed_array_; \
8834  ElementsKind elements_kind_; \
8835  };
8836 
8837 STORE_CONSTANT_TYPED_ARRAY(StoreIntConstantTypedArrayElement,
8838  OpProperties::CanWrite(),
8839  ValueRepresentation::kInt32, INT8_ELEMENTS,
8840  INT16_ELEMENTS, INT32_ELEMENTS, UINT8_ELEMENTS,
8842  UINT16_ELEMENTS, UINT32_ELEMENTS)
8843 STORE_CONSTANT_TYPED_ARRAY(StoreDoubleConstantTypedArrayElement,
8844  OpProperties::CanWrite(),
8845  ValueRepresentation::kHoleyFloat64, FLOAT32_ELEMENTS,
8846  FLOAT64_ELEMENTS)
8847 #undef STORE_CONSTANT_TYPED_ARRAY
8848 
8850  : public FixedInputNodeT<4, StoreSignedIntDataViewElement> {
8852 
8853  public:
8854  explicit StoreSignedIntDataViewElement(uint64_t bitfield,
8856  : Base(bitfield), type_(type) {
8860  }
8861 
8862  static constexpr OpProperties kProperties = OpProperties::CanWrite();
8863  static constexpr typename Base::InputTypes kInputTypes{
8864  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
8865  ValueRepresentation::kInt32, ValueRepresentation::kTagged};
8866 
8867  static constexpr int kObjectIndex = 0;
8868  static constexpr int kIndexIndex = 1;
8869  static constexpr int kValueIndex = 2;
8870  static constexpr int kIsLittleEndianIndex = 3;
8871  Input& object_input() { return input(kObjectIndex); }
8872  Input& index_input() { return input(kIndexIndex); }
8873  Input& value_input() { return input(kValueIndex); }
8874  Input& is_little_endian_input() { return input(kIsLittleEndianIndex); }
8875 
8877  return IsConstantNode(is_little_endian_input().node()->opcode());
8878  }
8879 
8882  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8883 
8884  ExternalArrayType type() const { return type_; }
8885 
8886  private:
8888 };
8889 
8891  : public FixedInputNodeT<4, StoreDoubleDataViewElement> {
8893 
8894  public:
8896  : Base(bitfield) {
8898  }
8899 
8900  static constexpr OpProperties kProperties = OpProperties::CanWrite();
8901  static constexpr typename Base::InputTypes kInputTypes{
8902  ValueRepresentation::kTagged, ValueRepresentation::kInt32,
8903  ValueRepresentation::kHoleyFloat64, ValueRepresentation::kTagged};
8904 
8905  static constexpr int kObjectIndex = 0;
8906  static constexpr int kIndexIndex = 1;
8907  static constexpr int kValueIndex = 2;
8908  static constexpr int kIsLittleEndianIndex = 3;
8909  Input& object_input() { return input(kObjectIndex); }
8910  Input& index_input() { return input(kIndexIndex); }
8911  Input& value_input() { return input(kValueIndex); }
8912  Input& is_little_endian_input() { return input(kIsLittleEndianIndex); }
8913 
8915  return IsConstantNode(is_little_endian_input().node()->opcode());
8916  }
8917 
8920  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
8921 };
8922 
8923 class StoreDoubleField : public FixedInputNodeT<2, StoreDoubleField> {
8925 
8926  public:
8927  explicit StoreDoubleField(uint64_t bitfield, int offset)
8928  : Base(bitfield), offset_(offset) {}
8929 
8930  static constexpr OpProperties kProperties = OpProperties::CanWrite();
8931  static constexpr typename Base::InputTypes kInputTypes{
8932  ValueRepresentation::kTagged, ValueRepresentation::kFloat64};
8933 
8934  int offset() const { return offset_; }
8935 
8936  static constexpr int kObjectIndex = 0;
8937  static constexpr int kValueIndex = 1;
8938  Input& object_input() { return input(kObjectIndex); }
8939  Input& value_input() { return input(kValueIndex); }
8940 
8943  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8944 
8945  private:
8946  const int offset_;
8947 };
8948 
8949 class StoreInt32 : public FixedInputNodeT<2, StoreInt32> {
8951 
8952  public:
8953  explicit StoreInt32(uint64_t bitfield, int offset)
8954  : Base(bitfield), offset_(offset) {}
8955 
8956  static constexpr OpProperties kProperties = OpProperties::CanWrite();
8957  static constexpr typename Base::InputTypes kInputTypes{
8958  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
8959 
8960  int offset() const { return offset_; }
8961 
8962  static constexpr int kObjectIndex = 0;
8963  static constexpr int kValueIndex = 1;
8964  Input& object_input() { return input(kObjectIndex); }
8965  Input& value_input() { return input(kValueIndex); }
8966 
8969  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8970 
8971  private:
8972  const int offset_;
8973 };
8974 
8975 class StoreFloat64 : public FixedInputNodeT<2, StoreFloat64> {
8977 
8978  public:
8979  explicit StoreFloat64(uint64_t bitfield, int offset)
8980  : Base(bitfield), offset_(offset) {}
8981 
8982  static constexpr OpProperties kProperties = OpProperties::CanWrite();
8983  static constexpr typename Base::InputTypes kInputTypes{
8984  ValueRepresentation::kTagged, ValueRepresentation::kFloat64};
8985 
8986  int offset() const { return offset_; }
8987 
8988  static constexpr int kObjectIndex = 0;
8989  static constexpr int kValueIndex = 1;
8990  Input& object_input() { return input(kObjectIndex); }
8991  Input& value_input() { return input(kValueIndex); }
8992 
8995  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
8996 
8997  private:
8998  const int offset_;
8999 };
9000 
9001 enum class StoreTaggedMode : uint8_t {
9002  kDefault,
9003  kInitializing,
9005 };
9007  return mode == StoreTaggedMode::kInitializing ||
9008  mode == StoreTaggedMode::kTransitioning;
9009 }
9010 
9012  : public FixedInputNodeT<2, StoreTaggedFieldNoWriteBarrier> {
9014 
9015  public:
9016  explicit StoreTaggedFieldNoWriteBarrier(uint64_t bitfield, int offset,
9017  StoreTaggedMode store_mode)
9018  : Base(bitfield | InitializingOrTransitioningField::encode(
9019  IsInitializingOrTransitioning(store_mode))),
9020  offset_(offset) {}
9021 
9022  // StoreTaggedFieldNoWriteBarrier never does a Deferred Call. However,
9023  // PhiRepresentationSelector can cause some StoreTaggedFieldNoWriteBarrier to
9024  // become StoreTaggedFieldWithWriteBarrier, which can do Deferred Calls, and
9025  // thus need the register snapshot. We thus set the DeferredCall property in
9026  // StoreTaggedFieldNoWriteBarrier so that it's allocated with enough space for
9027  // the register snapshot.
9028  static constexpr OpProperties kProperties =
9029  OpProperties::CanWrite() | OpProperties::DeferredCall();
9030  static constexpr typename Base::InputTypes kInputTypes{
9031  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9032 
9033  int offset() const { return offset_; }
9035  return InitializingOrTransitioningField::decode(bitfield());
9036  }
9037 
9038  static constexpr int kObjectIndex = 0;
9039  static constexpr int kValueIndex = 1;
9040  Input& object_input() { return input(kObjectIndex); }
9041  Input& value_input() { return input(kValueIndex); }
9042 
9043 #ifdef V8_COMPRESS_POINTERS
9044  void MarkTaggedInputsAsDecompressing() {
9045  object_input().node()->SetTaggedResultNeedsDecompress();
9046  // Don't need to decompress value to store it.
9047  }
9048 #endif
9049 
9050  int MaxCallStackArgs() const {
9051  // StoreTaggedFieldNoWriteBarrier never really does any call.
9052  return 0;
9053  }
9056  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9057 
9058  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
9059 
9060  private:
9061  using InitializingOrTransitioningField = NextBitField<bool, 1>;
9062 
9063  const int offset_;
9064 };
9065 
9066 class StoreMap : public FixedInputNodeT<1, StoreMap> {
9068 
9069  public:
9070  enum class Kind {
9071  kInitializing,
9072  kInlinedAllocation,
9074  };
9075  explicit StoreMap(uint64_t bitfield, compiler::MapRef map, Kind kind)
9076  : Base(bitfield | KindField::encode(kind)), map_(map) {}
9077 
9078  static constexpr OpProperties kProperties =
9079  OpProperties::CanWrite() | OpProperties::DeferredCall();
9080  static constexpr
9081  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
9082 
9083  static constexpr int kObjectIndex = 0;
9084  Input& object_input() { return input(kObjectIndex); }
9085 
9086  compiler::MapRef map() const { return map_; }
9087  Kind kind() const { return KindField::decode(bitfield()); }
9088 
9089  int MaxCallStackArgs() const;
9092  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9093 
9094  void ClearUnstableNodeAspects(KnownNodeAspects&);
9095 
9096  private:
9097  using KindField = NextBitField<Kind, 3>;
9099 };
9100 std::ostream& operator<<(std::ostream& os, StoreMap::Kind);
9101 
9103  : public FixedInputNodeT<2, StoreTaggedFieldWithWriteBarrier> {
9105 
9106  public:
9107  explicit StoreTaggedFieldWithWriteBarrier(uint64_t bitfield, int offset,
9108  StoreTaggedMode store_mode)
9109  : Base(bitfield | InitializingOrTransitioningField::encode(
9110  IsInitializingOrTransitioning(store_mode))),
9111  offset_(offset) {}
9112 
9113  static constexpr OpProperties kProperties =
9114  OpProperties::CanWrite() | OpProperties::DeferredCall();
9115  static constexpr typename Base::InputTypes kInputTypes{
9116  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9117 
9118  int offset() const { return offset_; }
9120  return InitializingOrTransitioningField::decode(bitfield());
9121  }
9122 
9123  static constexpr int kObjectIndex = 0;
9124  static constexpr int kValueIndex = 1;
9125  Input& object_input() { return input(kObjectIndex); }
9126  Input& value_input() { return input(kValueIndex); }
9127 
9128 #ifdef V8_COMPRESS_POINTERS
9129  void MarkTaggedInputsAsDecompressing() {
9130  object_input().node()->SetTaggedResultNeedsDecompress();
9131  // Don't need to decompress value to store it.
9132  }
9133 #endif
9134 
9135  int MaxCallStackArgs() const;
9138  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9139 
9140  private:
9141  using InitializingOrTransitioningField = NextBitField<bool, 1>;
9142 
9143  const int offset_;
9144 };
9145 
9147  : public FixedInputNodeT<2, StoreContextSlotWithWriteBarrier> {
9149 
9150  public:
9151  explicit StoreContextSlotWithWriteBarrier(uint64_t bitfield, int index)
9152  : Base(bitfield), index_(index) {}
9153 
9154  static constexpr OpProperties kProperties = OpProperties::CanWrite() |
9155  OpProperties::DeferredCall() |
9156  OpProperties::LazyDeopt();
9157  static constexpr typename Base::InputTypes kInputTypes{
9158  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9159 
9160  int offset() const { return Context::OffsetOfElementAt(index()); }
9161  int index() const { return index_; }
9162 
9163  static constexpr int kContextIndex = 0;
9164  static constexpr int kNewValueIndex = 1;
9165  Input& context_input() { return input(kContextIndex); }
9166  Input& new_value_input() { return input(kNewValueIndex); }
9167 
9168 #ifdef V8_COMPRESS_POINTERS
9169  void MarkTaggedInputsAsDecompressing() {
9170  context_input().node()->SetTaggedResultNeedsDecompress();
9171  new_value_input().node()->SetTaggedResultNeedsDecompress();
9172  }
9173 #endif
9174 
9175  int MaxCallStackArgs() const;
9178  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9179 
9180  private:
9181  const int index_;
9182 };
9183 
9185  : public FixedInputNodeT<2, StoreTrustedPointerFieldWithWriteBarrier> {
9187 
9188  public:
9189  explicit StoreTrustedPointerFieldWithWriteBarrier(uint64_t bitfield,
9190  int offset,
9191  IndirectPointerTag tag,
9192  StoreTaggedMode store_mode)
9193  : Base(bitfield | InitializingOrTransitioningField::encode(
9194  IsInitializingOrTransitioning(store_mode))),
9195  offset_(offset),
9196  tag_(tag) {}
9197 
9198  static constexpr OpProperties kProperties =
9199  OpProperties::CanWrite() | OpProperties::DeferredCall();
9200  static constexpr typename Base::InputTypes kInputTypes{
9201  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9202 
9203  int offset() const { return offset_; }
9204  IndirectPointerTag tag() const { return tag_; }
9206  return InitializingOrTransitioningField::decode(bitfield());
9207  }
9208 
9209  static constexpr int kObjectIndex = 0;
9210  static constexpr int kValueIndex = 1;
9211  Input& object_input() { return input(kObjectIndex); }
9212  Input& value_input() { return input(kValueIndex); }
9213 
9214 #ifdef V8_COMPRESS_POINTERS
9215  void MarkTaggedInputsAsDecompressing() {
9216  object_input().node()->SetTaggedResultNeedsDecompress();
9217  // value is never compressed.
9218  }
9219 #endif
9220 
9221  int MaxCallStackArgs() const;
9224  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9225 
9226  private:
9227  using InitializingOrTransitioningField = NextBitField<bool, 1>;
9228 
9229  const int offset_;
9231 };
9232 
9233 class LoadGlobal : public FixedInputValueNodeT<1, LoadGlobal> {
9235 
9236  public:
9237  explicit LoadGlobal(uint64_t bitfield, compiler::NameRef name,
9238  const compiler::FeedbackSource& feedback,
9239  TypeofMode typeof_mode)
9240  : Base(bitfield),
9241  name_(name),
9242  feedback_(feedback),
9243  typeof_mode_(typeof_mode) {}
9244 
9245  // The implementation currently calls runtime.
9246  static constexpr OpProperties kProperties = OpProperties::JSCall();
9247  static constexpr
9248  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
9249 
9250  compiler::NameRef name() const { return name_; }
9251  compiler::FeedbackSource feedback() const { return feedback_; }
9252  TypeofMode typeof_mode() const { return typeof_mode_; }
9253 
9254  Input& context() { return input(0); }
9255 
9256  int MaxCallStackArgs() const;
9259  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9260 
9261  private:
9265 };
9266 
9267 class StoreGlobal : public FixedInputValueNodeT<2, StoreGlobal> {
9269 
9270  public:
9271  explicit StoreGlobal(uint64_t bitfield, compiler::NameRef name,
9272  const compiler::FeedbackSource& feedback)
9273  : Base(bitfield), name_(name), feedback_(feedback) {}
9274 
9275  // The implementation currently calls runtime.
9276  static constexpr OpProperties kProperties = OpProperties::JSCall();
9277  static constexpr typename Base::InputTypes kInputTypes{
9278  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9279 
9280  compiler::NameRef name() const { return name_; }
9281  compiler::FeedbackSource feedback() const { return feedback_; }
9282 
9283  Input& context() { return input(0); }
9284  Input& value() { return input(1); }
9285 
9286  int MaxCallStackArgs() const;
9289  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9290 
9291  private:
9294 };
9295 
9297  : public FixedInputValueNodeT<3, UpdateJSArrayLength> {
9299 
9300  public:
9301  explicit UpdateJSArrayLength(uint64_t bitfield) : Base(bitfield) {}
9302 
9303  static constexpr OpProperties kProperties = OpProperties::CanWrite();
9304  static constexpr typename Base::InputTypes kInputTypes{
9305  ValueRepresentation::kInt32, ValueRepresentation::kTagged,
9306  ValueRepresentation::kInt32};
9307 
9308  // TODO(pthier): Use a more natural order once we can define the result
9309  // register to be equal to any input register.
9310  // The current order avoids any extra moves in the common case where index is
9311  // less than length
9312  static constexpr int kLengthIndex = 0;
9313  static constexpr int kObjectIndex = 1;
9314  static constexpr int kIndexIndex = 2;
9315  Input& length_input() { return input(kLengthIndex); }
9316  Input& object_input() { return input(kObjectIndex); }
9317  Input& index_input() { return input(kIndexIndex); }
9318 
9321  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9322 };
9323 
9324 class LoadNamedGeneric : public FixedInputValueNodeT<2, LoadNamedGeneric> {
9326 
9327  public:
9328  explicit LoadNamedGeneric(uint64_t bitfield, compiler::NameRef name,
9329  const compiler::FeedbackSource& feedback)
9330  : Base(bitfield), name_(name), feedback_(feedback) {}
9331 
9332  // The implementation currently calls runtime.
9333  static constexpr OpProperties kProperties = OpProperties::JSCall();
9334  static constexpr typename Base::InputTypes kInputTypes{
9335  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9336 
9337  compiler::NameRef name() const { return name_; }
9338  compiler::FeedbackSource feedback() const { return feedback_; }
9339 
9340  static constexpr int kContextIndex = 0;
9341  static constexpr int kObjectIndex = 1;
9342  Input& context() { return input(kContextIndex); }
9343  Input& object_input() { return input(kObjectIndex); }
9344 
9345  int MaxCallStackArgs() const;
9348  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9349 
9350  private:
9353 };
9354 
9356  : public FixedInputValueNodeT<3, LoadNamedFromSuperGeneric> {
9358 
9359  public:
9360  explicit LoadNamedFromSuperGeneric(uint64_t bitfield, compiler::NameRef name,
9361  const compiler::FeedbackSource& feedback)
9362  : Base(bitfield), name_(name), feedback_(feedback) {}
9363 
9364  // The implementation currently calls runtime.
9365  static constexpr OpProperties kProperties = OpProperties::JSCall();
9366  static constexpr typename Base::InputTypes kInputTypes{
9367  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9368  ValueRepresentation::kTagged};
9369 
9370  compiler::NameRef name() const { return name_; }
9371  compiler::FeedbackSource feedback() const { return feedback_; }
9372 
9373  static constexpr int kContextIndex = 0;
9374  static constexpr int kReceiverIndex = 1;
9375  static constexpr int kLookupStartObjectIndex = 2;
9376  Input& context() { return input(kContextIndex); }
9377  Input& receiver() { return input(kReceiverIndex); }
9378  Input& lookup_start_object() { return input(kLookupStartObjectIndex); }
9379 
9380  int MaxCallStackArgs() const;
9383  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9384 
9385  private:
9388 };
9389 
9390 class SetNamedGeneric : public FixedInputValueNodeT<3, SetNamedGeneric> {
9392 
9393  public:
9394  explicit SetNamedGeneric(uint64_t bitfield, compiler::NameRef name,
9395  const compiler::FeedbackSource& feedback)
9396  : Base(bitfield), name_(name), feedback_(feedback) {}
9397 
9398  // The implementation currently calls runtime.
9399  static constexpr OpProperties kProperties = OpProperties::JSCall();
9400  static constexpr typename Base::InputTypes kInputTypes{
9401  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9402  ValueRepresentation::kTagged};
9403 
9404  compiler::NameRef name() const { return name_; }
9405  compiler::FeedbackSource feedback() const { return feedback_; }
9406 
9407  static constexpr int kContextIndex = 0;
9408  static constexpr int kObjectIndex = 1;
9409  static constexpr int kValueIndex = 2;
9410  Input& context() { return input(kContextIndex); }
9411  Input& object_input() { return input(kObjectIndex); }
9412  Input& value_input() { return input(kValueIndex); }
9413 
9414  int MaxCallStackArgs() const;
9417  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9418 
9419  private:
9422 };
9423 
9425  : public FixedInputValueNodeT<1, LoadEnumCacheLength> {
9427 
9428  public:
9429  explicit LoadEnumCacheLength(uint64_t bitfield) : Base(bitfield) {}
9430 
9431  static constexpr OpProperties kProperties =
9432  OpProperties::CanRead() | OpProperties::Int32();
9433  static constexpr
9434  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
9435 
9436  static constexpr int kMapInput = 0;
9437  Input& map_input() { return input(kMapInput); }
9438 
9441  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9442 };
9443 
9444 class StringAt : public FixedInputValueNodeT<2, StringAt> {
9446 
9447  public:
9448  explicit StringAt(uint64_t bitfield) : Base(bitfield) {}
9449 
9450  static constexpr OpProperties kProperties = OpProperties::CanRead() |
9452  OpProperties::DeferredCall();
9453  static constexpr typename Base::InputTypes kInputTypes{
9454  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
9455 
9456  static constexpr int kStringIndex = 0;
9457  static constexpr int kIndexIndex = 1;
9458  Input& string_input() { return input(kStringIndex); }
9459  Input& index_input() { return input(kIndexIndex); }
9460 
9461  int MaxCallStackArgs() const;
9464  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9465 };
9466 
9467 class SeqOneByteStringAt : public FixedInputValueNodeT<2, SeqOneByteStringAt> {
9469 
9470  public:
9471  explicit SeqOneByteStringAt(uint64_t bitfield) : Base(bitfield) {}
9472 
9473  static constexpr OpProperties kProperties = OpProperties::CanRead();
9474  static constexpr typename Base::InputTypes kInputTypes{
9475  ValueRepresentation::kTagged, ValueRepresentation::kInt32};
9476 
9477  static constexpr int kStringIndex = 0;
9478  static constexpr int kIndexIndex = 1;
9479  Input& string_input() { return input(kStringIndex); }
9480  Input& index_input() { return input(kIndexIndex); }
9481 
9484  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9485 };
9486 
9487 class StringLength : public FixedInputValueNodeT<1, StringLength> {
9489 
9490  public:
9491  explicit StringLength(uint64_t bitfield) : Base(bitfield) {}
9492 
9493  static constexpr OpProperties kProperties =
9494  OpProperties::CanRead() | OpProperties::Int32();
9495  static constexpr
9496  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
9497 
9498  static constexpr int kObjectIndex = 0;
9499  Input& object_input() { return input(kObjectIndex); }
9500 
9501  int MaxCallStackArgs() const;
9504  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9505 };
9506 
9507 class StringConcat : public FixedInputValueNodeT<2, StringConcat> {
9509 
9510  public:
9511  explicit StringConcat(uint64_t bitfield) : Base(bitfield) {}
9512 
9513  static constexpr OpProperties kProperties =
9514  OpProperties::Call() | OpProperties::CanAllocate() |
9515  OpProperties::LazyDeopt() | OpProperties::CanThrow();
9516  static constexpr typename Base::InputTypes kInputTypes{
9517  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9518 
9519  Input& lhs() { return Node::input(0); }
9520  Input& rhs() { return Node::input(1); }
9521 
9522  int MaxCallStackArgs() const { return 0; }
9525  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9526 };
9527 
9528 /*
9529  * This instruction takes two string map inputs and returns the result map that
9530  * is required for a cons string of these two inputs types (i.e.,
9531  * Const(One|Two)ByteStringMap).
9532  *
9533  * TODO(olivf): Remove this instruction and instead select the result map using
9534  * normal branches. This needs allocation folding support across the resulting
9535  * sub-graph.
9536  *
9537  */
9538 class ConsStringMap : public FixedInputValueNodeT<2, ConsStringMap> {
9540 
9541  public:
9542  explicit ConsStringMap(uint64_t bitfield) : Base(bitfield) {}
9543 
9544  static constexpr OpProperties kProperties = OpProperties::TaggedValue();
9545 
9546  static constexpr typename Base::InputTypes kInputTypes{
9547  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9548 
9549  Input& lhs() { return Node::input(0); }
9550  Input& rhs() { return Node::input(1); }
9551 
9552 #ifdef V8_STATIC_ROOTS
9553  void MarkTaggedInputsAsDecompressing() const {
9554  // Not needed as we just check some bits on the map ptr.
9555  }
9556 #endif
9557 
9558  int MaxCallStackArgs() const { return 0; }
9561  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9562 };
9563 
9565  : public FixedInputValueNodeT<1, UnwrapStringWrapper> {
9567 
9568  public:
9569  explicit UnwrapStringWrapper(uint64_t bitfield) : Base(bitfield) {}
9570 
9571  static constexpr OpProperties kProperties = OpProperties::TaggedValue();
9572 
9573  static constexpr
9574  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
9575 
9576  Input& value_input() { return Node::input(0); }
9577 
9578  int MaxCallStackArgs() const { return 0; }
9581  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9582 };
9583 
9585  : public FixedInputValueNodeT<3, DefineNamedOwnGeneric> {
9587 
9588  public:
9589  explicit DefineNamedOwnGeneric(uint64_t bitfield, compiler::NameRef name,
9590  const compiler::FeedbackSource& feedback)
9591  : Base(bitfield), name_(name), feedback_(feedback) {}
9592 
9593  // The implementation currently calls runtime.
9594  static constexpr OpProperties kProperties = OpProperties::JSCall();
9595  static constexpr typename Base::InputTypes kInputTypes{
9596  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9597  ValueRepresentation::kTagged};
9598 
9599  compiler::NameRef name() const { return name_; }
9600  compiler::FeedbackSource feedback() const { return feedback_; }
9601 
9602  static constexpr int kContextIndex = 0;
9603  static constexpr int kObjectIndex = 1;
9604  static constexpr int kValueIndex = 2;
9605  Input& context() { return input(kContextIndex); }
9606  Input& object_input() { return input(kObjectIndex); }
9607  Input& value_input() { return input(kValueIndex); }
9608 
9609  int MaxCallStackArgs() const;
9612  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9613 
9614  private:
9617 };
9618 
9620  : public FixedInputValueNodeT<4, StoreInArrayLiteralGeneric> {
9622 
9623  public:
9624  explicit StoreInArrayLiteralGeneric(uint64_t bitfield,
9625  const compiler::FeedbackSource& feedback)
9626  : Base(bitfield), feedback_(feedback) {}
9627 
9628  // The implementation currently calls runtime.
9629  static constexpr OpProperties kProperties = OpProperties::JSCall();
9630  static constexpr typename Base::InputTypes kInputTypes{
9631  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9632  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9633 
9634  compiler::FeedbackSource feedback() const { return feedback_; }
9635 
9636  static constexpr int kContextIndex = 0;
9637  static constexpr int kObjectIndex = 1;
9638  static constexpr int kNameIndex = 2;
9639  static constexpr int kValueIndex = 3;
9640  Input& context() { return input(kContextIndex); }
9641  Input& object_input() { return input(kObjectIndex); }
9642  Input& name_input() { return input(kNameIndex); }
9643  Input& value_input() { return input(kValueIndex); }
9644 
9645  int MaxCallStackArgs() const;
9648  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9649 
9650  private:
9652 };
9653 
9654 class GetKeyedGeneric : public FixedInputValueNodeT<3, GetKeyedGeneric> {
9656 
9657  public:
9658  explicit GetKeyedGeneric(uint64_t bitfield,
9659  const compiler::FeedbackSource& feedback)
9660  : Base(bitfield), feedback_(feedback) {}
9661 
9662  // The implementation currently calls runtime.
9663  static constexpr OpProperties kProperties = OpProperties::JSCall();
9664  static constexpr typename Base::InputTypes kInputTypes{
9665  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9666  ValueRepresentation::kTagged};
9667 
9668  compiler::FeedbackSource feedback() const { return feedback_; }
9669 
9670  static constexpr int kContextIndex = 0;
9671  static constexpr int kObjectIndex = 1;
9672  static constexpr int kKeyIndex = 2;
9673  Input& context() { return input(kContextIndex); }
9674  Input& object_input() { return input(kObjectIndex); }
9675  Input& key_input() { return input(kKeyIndex); }
9676 
9677  int MaxCallStackArgs() const;
9680  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9681 
9682  private:
9684 };
9685 
9686 class SetKeyedGeneric : public FixedInputValueNodeT<4, SetKeyedGeneric> {
9688 
9689  public:
9690  explicit SetKeyedGeneric(uint64_t bitfield,
9691  const compiler::FeedbackSource& feedback)
9692  : Base(bitfield), feedback_(feedback) {}
9693 
9694  // The implementation currently calls runtime.
9695  static constexpr OpProperties kProperties = OpProperties::JSCall();
9696  static constexpr typename Base::InputTypes kInputTypes{
9697  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9698  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
9699 
9700  compiler::FeedbackSource feedback() const { return feedback_; }
9701 
9702  static constexpr int kContextIndex = 0;
9703  static constexpr int kObjectIndex = 1;
9704  static constexpr int kKeyIndex = 2;
9705  static constexpr int kValueIndex = 3;
9706  Input& context() { return input(kContextIndex); }
9707  Input& object_input() { return input(kObjectIndex); }
9708  Input& key_input() { return input(kKeyIndex); }
9709  Input& value_input() { return input(kValueIndex); }
9710 
9711  int MaxCallStackArgs() const;
9714  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9715 
9716  private:
9718 };
9719 
9721  : public FixedInputValueNodeT<5, DefineKeyedOwnGeneric> {
9723 
9724  public:
9725  explicit DefineKeyedOwnGeneric(uint64_t bitfield,
9726  const compiler::FeedbackSource& feedback)
9727  : Base(bitfield), feedback_(feedback) {}
9728 
9729  // The implementation currently calls runtime.
9730  static constexpr OpProperties kProperties = OpProperties::JSCall();
9731  static constexpr typename Base::InputTypes kInputTypes{
9732  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9733  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
9734  ValueRepresentation::kTagged};
9735 
9736  compiler::FeedbackSource feedback() const { return feedback_; }
9737 
9738  static constexpr int kContextIndex = 0;
9739  static constexpr int kObjectIndex = 1;
9740  static constexpr int kKeyIndex = 2;
9741  static constexpr int kValueIndex = 3;
9742  static constexpr int kFlagsIndex = 4;
9743  Input& context() { return input(kContextIndex); }
9744  Input& object_input() { return input(kObjectIndex); }
9745  Input& key_input() { return input(kKeyIndex); }
9746  Input& value_input() { return input(kValueIndex); }
9747  Input& flags_input() { return input(kFlagsIndex); }
9748 
9749  int MaxCallStackArgs() const;
9752  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
9753 
9754  private:
9756 };
9757 
9758 class GapMove : public FixedInputNodeT<0, GapMove> {
9760 
9761  public:
9762  GapMove(uint64_t bitfield, compiler::AllocatedOperand source,
9764  : Base(bitfield), source_(source), target_(target) {}
9765 
9766  compiler::AllocatedOperand source() const { return source_; }
9767  compiler::AllocatedOperand target() const { return target_; }
9768 
9771  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9772 
9773  private:
9776 };
9777 
9778 class ConstantGapMove : public FixedInputNodeT<0, ConstantGapMove> {
9780 
9781  public:
9782  ConstantGapMove(uint64_t bitfield, ValueNode* node,
9784  : Base(bitfield), node_(node), target_(target) {}
9785 
9786  compiler::AllocatedOperand target() const { return target_; }
9787  ValueNode* node() const { return node_; }
9788 
9791  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9792 
9793  private:
9797 };
9798 
9800 
9801 // ValueRepresentation doesn't distinguish between Int32 and TruncatedInt32:
9802 // both are Int32. For Phi untagging however, it's interesting to have a
9803 // difference between the 2, as a TruncatedInt32 would allow untagging to
9804 // Float64, whereas an Int32 use wouldn't (because it would require a deopting
9805 // Float64->Int32 conversion, whereas the truncating version of this conversion
9806 // cannot deopt). We thus use a UseRepresentation to record use hints for Phis.
9807 enum class UseRepresentation : uint8_t {
9808  kTagged,
9809  kInt32,
9811  kUint32,
9812  kFloat64,
9813  kHoleyFloat64,
9814 };
9815 
9816 inline std::ostream& operator<<(std::ostream& os,
9817  const UseRepresentation& repr) {
9818  switch (repr) {
9819  case UseRepresentation::kTagged:
9820  return os << "Tagged";
9821  case UseRepresentation::kInt32:
9822  return os << "Int32";
9823  case UseRepresentation::kTruncatedInt32:
9824  return os << "TruncatedInt32";
9825  case UseRepresentation::kUint32:
9826  return os << "Uint32";
9827  case UseRepresentation::kFloat64:
9828  return os << "Float64";
9829  case UseRepresentation::kHoleyFloat64:
9830  return os << "HoleyFloat64";
9831  }
9832 }
9833 
9836 
9837 // TODO(verwaest): It may make more sense to buffer phis in merged_states until
9838 // we set up the interpreter frame state for code generation. At that point we
9839 // can generate correctly-sized phis.
9840 class Phi : public ValueNodeT<Phi> {
9842 
9843  public:
9845 
9846  // TODO(jgruber): More intuitive constructors, if possible.
9847  Phi(uint64_t bitfield, MergePointInterpreterFrameState* merge_state,
9848  interpreter::Register owner)
9849  : Base(bitfield),
9850  owner_(owner),
9851  merge_state_(merge_state),
9852  type_(NodeType::kUnknown),
9853  post_loop_type_(NodeType::kUnknown) {
9854  DCHECK_NOT_NULL(merge_state);
9855  }
9856 
9857  Input& backedge_input() { return input(input_count() - 1); }
9858 
9859  interpreter::Register owner() const { return owner_; }
9861  return merge_state_;
9862  }
9863 
9864  using Node::initialize_input_null;
9865  using Node::reduce_input_count;
9866  using Node::set_input;
9867 
9868  bool is_exception_phi() const { return input_count() == 0; }
9869  bool is_loop_phi() const;
9870 
9871  bool is_backedge_offset(int i) const {
9872  return is_loop_phi() && i == input_count() - 1;
9873  }
9874 
9875  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
9876 
9877 #ifdef V8_COMPRESS_POINTERS
9878  void MarkTaggedInputsAsDecompressing() {
9879  // Do not mark inputs as decompressing here, since we don't yet know whether
9880  // this Phi needs decompression. Instead, let
9881  // Node::SetTaggedResultNeedsDecompress pass through phis.
9882  }
9883 #endif
9884 
9887  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
9888 
9889  BasicBlock* predecessor_at(int i);
9890 
9892  RecordUseReprHint(UseRepresentationSet{repr});
9893  }
9894 
9895  void RecordUseReprHint(UseRepresentationSet repr_mask);
9896 
9897  UseRepresentationSet get_uses_repr_hints() { return uses_repr_hint_; }
9899  return same_loop_uses_repr_hint_;
9900  }
9901 
9902  NodeType post_loop_type() const { return post_loop_type_; }
9904  DCHECK(!has_key());
9905  post_loop_type_ = UnionType(post_loop_type_, type);
9906  }
9908  DCHECK(!has_key());
9909  DCHECK(is_unmerged_loop_phi());
9910  post_loop_type_ = type;
9911  }
9913  DCHECK(!has_key());
9914  DCHECK(is_unmerged_loop_phi());
9915  DCHECK(NodeTypeIs(post_loop_type_, type_));
9916  type_ = post_loop_type_;
9917  }
9918 
9920  DCHECK(!has_key());
9921  type_ = UnionType(type_, type);
9922  }
9924  DCHECK(!has_key());
9925  type_ = type;
9926  }
9927  NodeType type() const {
9928  DCHECK(!has_key());
9929  return type_;
9930  }
9931 
9933  Key key() const {
9934  DCHECK(has_key());
9935  return key_;
9936  }
9937  void set_key(Key key) {
9938  set_bitfield(bitfield() | HasKeyFlag::encode(true));
9939  key_ = key;
9940  }
9941 
9942  // True if the {key_} field has been initialized.
9943  bool has_key() const { return HasKeyFlag::decode(bitfield()); }
9944 
9945  // Remembers if a use is unsafely untagged. If that happens we must ensure to
9946  // stay within the smi range, even when untagging.
9947  void SetUseRequires31BitValue();
9949  return Requires31BitValueFlag::decode(bitfield());
9950  }
9952  set_bitfield(bitfield() | Requires31BitValueFlag::encode(true));
9953  }
9954 
9955  // Check if a phi has cleared the loop.
9956  bool is_unmerged_loop_phi() const;
9957 
9958  private:
9959  Phi** next() { return &next_; }
9960 
9961  using HasKeyFlag = NextBitField<bool, 1>;
9962  using Requires31BitValueFlag = HasKeyFlag::Next<bool, 1>;
9963  using LoopPhiAfterLoopFlag = Requires31BitValueFlag::Next<bool, 1>;
9964 
9966 
9967  UseRepresentationSet uses_repr_hint_ = {};
9968  UseRepresentationSet same_loop_uses_repr_hint_ = {};
9969 
9970  Phi* next_ = nullptr;
9972 
9973  union {
9974  struct {
9975  // The type of this Phi based on its predecessors' types.
9977  // {type_} for loop Phis should always be Unknown until their backedge has
9978  // been bound (because we don't know what will be the type of the
9979  // backedge). However, once the backedge is bound, we might be able to
9980  // refine it. {post_loop_type_} is thus used to keep track of loop Phi
9981  // types: for loop Phis, we update {post_loop_type_} when we merge
9982  // predecessors, but keep {type_} as Unknown. Once the backedge is bound,
9983  // we set {type_} as {post_loop_type_}.
9985  };
9986  // After graph building, {type_} and {post_loop_type_} are not used anymore,
9987  // so we reuse this memory to store the SnapshotTable Key for this Phi for
9988  // phi untagging.
9990  };
9991 
9993 };
9994 
9995 class Call : public ValueNodeT<Call> {
9997 
9998  public:
9999  enum class TargetType { kJSFunction, kAny };
10000  // We assume function and context as fixed inputs.
10001  static constexpr int kFunctionIndex = 0;
10002  static constexpr int kContextIndex = 1;
10003  static constexpr int kFixedInputCount = 2;
10004 
10005  // We need enough inputs to have these fixed inputs plus the maximum arguments
10006  // to a function call.
10007  static_assert(kMaxInputs >= kFixedInputCount + Code::kMaxArguments);
10008 
10009  // This ctor is used when for variable input counts.
10010  // Inputs must be initialized manually.
10011  Call(uint64_t bitfield, ConvertReceiverMode mode, TargetType target_type,
10012  ValueNode* function, ValueNode* context)
10013  : Base(bitfield), receiver_mode_(mode), target_type_(target_type) {
10014  set_input(kFunctionIndex, function);
10015  set_input(kContextIndex, context);
10016  }
10017 
10018  static constexpr OpProperties kProperties = OpProperties::JSCall();
10019 
10020  Input& function() { return input(kFunctionIndex); }
10021  const Input& function() const { return input(kFunctionIndex); }
10022  Input& context() { return input(kContextIndex); }
10023  const Input& context() const { return input(kContextIndex); }
10024  int num_args() const { return input_count() - kFixedInputCount; }
10025  Input& arg(int i) { return input(i + kFixedInputCount); }
10026  void set_arg(int i, ValueNode* node) {
10027  set_input(i + kFixedInputCount, node);
10028  }
10029  auto args() {
10031  std::make_reverse_iterator(&arg(-1)),
10032  std::make_reverse_iterator(&arg(num_args() - 1)));
10033  }
10034 
10035  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10036 #ifdef V8_COMPRESS_POINTERS
10037  void MarkTaggedInputsAsDecompressing();
10038 #endif
10039  int MaxCallStackArgs() const;
10042  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10043 
10044  ConvertReceiverMode receiver_mode() const { return receiver_mode_; }
10045  TargetType target_type() const { return target_type_; }
10046 
10047  private:
10050 };
10051 
10052 class Construct : public ValueNodeT<Construct> {
10054 
10055  public:
10056  // We assume function and context as fixed inputs.
10057  static constexpr int kFunctionIndex = 0;
10058  static constexpr int kNewTargetIndex = 1;
10059  static constexpr int kContextIndex = 2;
10060  static constexpr int kFixedInputCount = 3;
10061 
10062  // We need enough inputs to have these fixed inputs plus the maximum arguments
10063  // to a function call.
10064  static_assert(kMaxInputs >= kFixedInputCount + Code::kMaxArguments);
10065 
10066  // This ctor is used when for variable input counts.
10067  // Inputs must be initialized manually.
10068  Construct(uint64_t bitfield, const compiler::FeedbackSource& feedback,
10069  ValueNode* function, ValueNode* new_target, ValueNode* context)
10070  : Base(bitfield), feedback_(feedback) {
10071  set_input(kFunctionIndex, function);
10072  set_input(kNewTargetIndex, new_target);
10073  set_input(kContextIndex, context);
10074  }
10075 
10076  static constexpr OpProperties kProperties = OpProperties::JSCall();
10077 
10078  Input& function() { return input(kFunctionIndex); }
10079  const Input& function() const { return input(kFunctionIndex); }
10080  Input& new_target() { return input(kNewTargetIndex); }
10081  const Input& new_target() const { return input(kNewTargetIndex); }
10082  Input& context() { return input(kContextIndex); }
10083  const Input& context() const { return input(kContextIndex); }
10084  int num_args() const { return input_count() - kFixedInputCount; }
10085  Input& arg(int i) { return input(i + kFixedInputCount); }
10086  void set_arg(int i, ValueNode* node) {
10087  set_input(i + kFixedInputCount, node);
10088  }
10089  auto args() {
10091  std::make_reverse_iterator(&arg(-1)),
10092  std::make_reverse_iterator(&arg(num_args() - 1)));
10093  }
10094 
10095  compiler::FeedbackSource feedback() const { return feedback_; }
10096 
10097  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10098 #ifdef V8_COMPRESS_POINTERS
10099  void MarkTaggedInputsAsDecompressing();
10100 #endif
10101  int MaxCallStackArgs() const;
10104  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10105 
10106  private:
10108 };
10109 
10110 class CallBuiltin : public ValueNodeT<CallBuiltin> {
10112 
10113  public:
10114  enum FeedbackSlotType { kTaggedIndex, kSmi };
10115 
10116  // This ctor is used when for variable input counts.
10117  // Inputs must be initialized manually.
10118  CallBuiltin(uint64_t bitfield, Builtin builtin)
10119  : Base(bitfield), builtin_(builtin) {
10120  DCHECK(
10121  !Builtins::CallInterfaceDescriptorFor(builtin).HasContextParameter());
10122  }
10123 
10124  // This ctor is used when for variable input counts.
10125  // Inputs must be initialized manually.
10126  CallBuiltin(uint64_t bitfield, Builtin builtin, ValueNode* context)
10127  : Base(bitfield), builtin_(builtin) {
10128  DCHECK(Builtins::CallInterfaceDescriptorFor(builtin).HasContextParameter());
10129  // We use the last valid input for the context.
10130  set_input(input_count() - 1, context);
10131  }
10132 
10133  // This is an overestimation, since some builtins might not call JS code.
10134  static constexpr OpProperties kProperties = OpProperties::JSCall();
10135 
10136  bool has_feedback() const { return feedback_.has_value(); }
10138  DCHECK(has_feedback());
10139  return feedback_.value();
10140  }
10142  DCHECK(has_feedback());
10143  return slot_type_;
10144  }
10146  FeedbackSlotType slot_type) {
10147  feedback_ = feedback;
10148  slot_type_ = slot_type;
10149  }
10150 
10151  Builtin builtin() const { return builtin_; }
10153  DCHECK(
10154  Builtins::CallInterfaceDescriptorFor(builtin()).HasContextParameter());
10155  return input(input_count() - 1);
10156  }
10157 
10159  auto descriptor = Builtins::CallInterfaceDescriptorFor(builtin_);
10160  bool has_context = descriptor.HasContextParameter();
10161  int extra_input_count = has_context ? 1 : 0;
10162  return input_count() - extra_input_count;
10163  }
10164 
10166  auto descriptor = Builtins::CallInterfaceDescriptorFor(builtin_);
10167  if (has_feedback()) {
10168  int slot_index = InputCountWithoutContext();
10169  int vector_index = slot_index + 1;
10170 
10171  // There are three possibilities:
10172  // 1. Feedback slot and vector are in register.
10173  // 2. Feedback slot is in register and vector is on stack.
10174  // 3. Feedback slot and vector are on stack.
10175  if (vector_index < descriptor.GetRegisterParameterCount()) {
10176  return descriptor.GetRegisterParameterCount() - 2;
10177  } else if (vector_index == descriptor.GetRegisterParameterCount()) {
10178  return descriptor.GetRegisterParameterCount() - 1;
10179  } else {
10180  return descriptor.GetRegisterParameterCount();
10181  }
10182  }
10183  return descriptor.GetRegisterParameterCount();
10184  }
10185 
10186  auto stack_args() {
10188  std::make_reverse_iterator(&input(InputsInRegisterCount() - 1)),
10189  std::make_reverse_iterator(&input(InputCountWithoutContext() - 1)));
10190  }
10191 
10192  void set_arg(int i, ValueNode* node) { set_input(i, node); }
10193 
10194  int ReturnCount() const {
10195  return Builtins::CallInterfaceDescriptorFor(builtin_).GetReturnCount();
10196  }
10197 
10198  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10199 #ifdef V8_COMPRESS_POINTERS
10200  void MarkTaggedInputsAsDecompressing();
10201 #endif
10202  int MaxCallStackArgs() const;
10205  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10206 
10207  private:
10208  template <typename... Args>
10209  void PushArguments(MaglevAssembler* masm, Args... extra_args);
10212 
10214  std::optional<compiler::FeedbackSource> feedback_;
10215  FeedbackSlotType slot_type_ = kTaggedIndex;
10216 };
10217 
10218 class CallCPPBuiltin : public ValueNodeT<CallCPPBuiltin> {
10220  // Only 1 return value with arguments on the stack is supported.
10221  static constexpr Builtin kCEntry_Builtin =
10222  Builtin::kCEntry_Return1_ArgvOnStack_BuiltinExit;
10223 
10224  public:
10225  static constexpr int kTargetIndex = 0;
10226  static constexpr int kNewTargetIndex = 1;
10227  static constexpr int kContextIndex = 2;
10228  static constexpr int kFixedInputCount = 3;
10229 
10230  CallCPPBuiltin(uint64_t bitfield, Builtin builtin, ValueNode* target,
10231  ValueNode* new_target, ValueNode* context)
10232  : Base(bitfield), builtin_(builtin) {
10233  DCHECK(Builtins::CallInterfaceDescriptorFor(builtin).HasContextParameter());
10234  DCHECK_EQ(Builtins::CallInterfaceDescriptorFor(builtin).GetReturnCount(),
10235  1);
10236  set_input(kTargetIndex, target);
10237  set_input(kNewTargetIndex, new_target);
10238  set_input(kContextIndex, context);
10239  }
10240 
10241  // This is an overestimation, since some builtins might not call JS code.
10242  static constexpr OpProperties kProperties = OpProperties::JSCall();
10243 
10244  Builtin builtin() const { return builtin_; }
10245 
10246  Input& target() { return input(kTargetIndex); }
10247  const Input& target() const { return input(kTargetIndex); }
10248  Input& new_target() { return input(kNewTargetIndex); }
10249  const Input& new_target() const { return input(kNewTargetIndex); }
10250  Input& context() { return input(kContextIndex); }
10251  const Input& context() const { return input(kContextIndex); }
10252 
10253  int num_args() const { return input_count() - kFixedInputCount; }
10254  Input& arg(int i) { return input(i + kFixedInputCount); }
10255  void set_arg(int i, ValueNode* node) {
10256  set_input(i + kFixedInputCount, node);
10257  }
10258 
10259  auto args() {
10261  std::make_reverse_iterator(&arg(-1)),
10262  std::make_reverse_iterator(&arg(num_args() - 1)));
10263  }
10264 
10265  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10266 #ifdef V8_COMPRESS_POINTERS
10267  void MarkTaggedInputsAsDecompressing();
10268 #endif
10269  int MaxCallStackArgs() const;
10272  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10273 
10274  private:
10276 };
10277 
10278 class CallForwardVarargs : public ValueNodeT<CallForwardVarargs> {
10280 
10281  public:
10282  static constexpr int kFunctionIndex = 0;
10283  static constexpr int kContextIndex = 1;
10284  static constexpr int kFixedInputCount = 2;
10285 
10286  // We need enough inputs to have these fixed inputs plus the maximum arguments
10287  // to a function call.
10288  static_assert(kMaxInputs >= kFixedInputCount + Code::kMaxArguments);
10289 
10290  // This ctor is used when for variable input counts.
10291  // Inputs must be initialized manually.
10292  CallForwardVarargs(uint64_t bitfield, ValueNode* function, ValueNode* context,
10293  int start_index, Call::TargetType target_type)
10294  : Base(bitfield), start_index_(start_index), target_type_(target_type) {
10295  set_input(kFunctionIndex, function);
10296  set_input(kContextIndex, context);
10297  }
10298 
10299  static constexpr OpProperties kProperties = OpProperties::JSCall();
10300 
10301  Input& function() { return input(kFunctionIndex); }
10302  const Input& function() const { return input(kFunctionIndex); }
10303  Input& context() { return input(kContextIndex); }
10304  const Input& context() const { return input(kContextIndex); }
10305  int num_args() const { return input_count() - kFixedInputCount; }
10306  Input& arg(int i) { return input(i + kFixedInputCount); }
10307  void set_arg(int i, ValueNode* node) {
10308  set_input(i + kFixedInputCount, node);
10309  }
10310  auto args() {
10312  std::make_reverse_iterator(&arg(-1)),
10313  std::make_reverse_iterator(&arg(num_args() - 1)));
10314  }
10315 
10316  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10317 #ifdef V8_COMPRESS_POINTERS
10318  void MarkTaggedInputsAsDecompressing();
10319 #endif
10320  int MaxCallStackArgs() const;
10323  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10324 
10325  int start_index() const { return start_index_; }
10326  Call::TargetType target_type() const { return target_type_; }
10327 
10328  private:
10331 };
10332 
10333 class CallRuntime : public ValueNodeT<CallRuntime> {
10335 
10336  public:
10337  // We assume the context as fixed input.
10338  static constexpr int kContextIndex = 0;
10339  static constexpr int kFixedInputCount = 1;
10340 
10341  // This ctor is used when for variable input counts.
10342  // Inputs must be initialized manually.
10343  CallRuntime(uint64_t bitfield, Runtime::FunctionId function_id,
10344  ValueNode* context)
10345  : Base(bitfield), function_id_(function_id) {
10346  set_input(kContextIndex, context);
10347  }
10348 
10349  static constexpr OpProperties kProperties = OpProperties::JSCall();
10350 
10351  Runtime::FunctionId function_id() const { return function_id_; }
10352 
10353  Input& context() { return input(kContextIndex); }
10354  const Input& context() const { return input(kContextIndex); }
10355  int num_args() const { return input_count() - kFixedInputCount; }
10356  Input& arg(int i) { return input(i + kFixedInputCount); }
10357  void set_arg(int i, ValueNode* node) {
10358  set_input(i + kFixedInputCount, node);
10359  }
10360  auto args() {
10362  std::make_reverse_iterator(&arg(-1)),
10363  std::make_reverse_iterator(&arg(num_args() - 1)));
10364  }
10365 
10366  int ReturnCount() const {
10367  return Runtime::FunctionForId(function_id())->result_size;
10368  }
10369 
10370  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10371 #ifdef V8_COMPRESS_POINTERS
10372  void MarkTaggedInputsAsDecompressing();
10373 #endif
10374  int MaxCallStackArgs() const;
10377  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10378 
10379  private:
10381 };
10382 
10383 class CallWithSpread : public ValueNodeT<CallWithSpread> {
10385 
10386  public:
10387  // We assume function and context as fixed inputs.
10388  static constexpr int kFunctionIndex = 0;
10389  static constexpr int kContextIndex = 1;
10390  static constexpr int kFixedInputCount = 2;
10391 
10392  // This ctor is used when for variable input counts.
10393  // Inputs must be initialized manually.
10394  CallWithSpread(uint64_t bitfield, ValueNode* function, ValueNode* context)
10395  : Base(bitfield) {
10396  set_input(kFunctionIndex, function);
10397  set_input(kContextIndex, context);
10398  }
10399 
10400  static constexpr OpProperties kProperties = OpProperties::JSCall();
10401 
10402  Input& function() { return input(kFunctionIndex); }
10403  const Input& function() const { return input(kFunctionIndex); }
10404  Input& context() { return input(kContextIndex); }
10405  const Input& context() const { return input(kContextIndex); }
10406  int num_args() const { return input_count() - kFixedInputCount; }
10407  int num_args_no_spread() const {
10408  DCHECK_GT(num_args(), 0);
10409  return num_args() - 1;
10410  }
10411  Input& arg(int i) { return input(i + kFixedInputCount); }
10412  void set_arg(int i, ValueNode* node) {
10413  set_input(i + kFixedInputCount, node);
10414  }
10417  std::make_reverse_iterator(&arg(-1)),
10418  std::make_reverse_iterator(&arg(num_args_no_spread() - 1)));
10419  }
10421  // Spread is the last argument/input.
10422  return input(input_count() - 1);
10423  }
10424  Input& receiver() { return arg(0); }
10425 
10426  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10427 #ifdef V8_COMPRESS_POINTERS
10428  void MarkTaggedInputsAsDecompressing();
10429 #endif
10430  int MaxCallStackArgs() const;
10433  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10434 };
10435 
10436 class CallWithArrayLike : public FixedInputValueNodeT<4, CallWithArrayLike> {
10438 
10439  public:
10440  // We assume function and context as fixed inputs.
10441  static constexpr int kFunctionIndex = 0;
10442  static constexpr int kReceiverIndex = 1;
10443  static constexpr int kArgumentsListIndex = 2;
10444  static constexpr int kContextIndex = 3;
10445 
10446  // This ctor is used when for variable input counts.
10447  // Inputs must be initialized manually.
10448  explicit CallWithArrayLike(uint64_t bitfield) : Base(bitfield) {}
10449 
10450  static constexpr OpProperties kProperties = OpProperties::JSCall();
10451  static constexpr typename Base::InputTypes kInputTypes{
10452  ValueRepresentation::kTagged, ValueRepresentation::kTagged,
10453  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
10454 
10455  Input& function() { return input(kFunctionIndex); }
10456  Input& receiver() { return input(kReceiverIndex); }
10457  Input& arguments_list() { return input(kArgumentsListIndex); }
10458  Input& context() { return input(kContextIndex); }
10459 
10460  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10461 #ifdef V8_COMPRESS_POINTERS
10462  void MarkTaggedInputsAsDecompressing();
10463 #endif
10464  int MaxCallStackArgs() const;
10467  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10468 };
10469 
10470 class CallSelf : public ValueNodeT<CallSelf> {
10472 
10473  public:
10474  static constexpr int kClosureIndex = 0;
10475  static constexpr int kContextIndex = 1;
10476  static constexpr int kReceiverIndex = 2;
10477  static constexpr int kNewTargetIndex = 3;
10478  static constexpr int kFixedInputCount = 4;
10479 
10480  // We need enough inputs to have these fixed inputs plus the maximum arguments
10481  // to a function call.
10482  static_assert(kMaxInputs >= kFixedInputCount + Code::kMaxArguments);
10483 
10484  // This ctor is used when for variable input counts.
10485  // Inputs must be initialized manually.
10486  CallSelf(uint64_t bitfield, int expected_parameter_count, ValueNode* closure,
10487  ValueNode* context, ValueNode* receiver, ValueNode* new_target)
10488  : Base(bitfield), expected_parameter_count_(expected_parameter_count) {
10489  set_input(kClosureIndex, closure);
10490  set_input(kContextIndex, context);
10491  set_input(kReceiverIndex, receiver);
10492  set_input(kNewTargetIndex, new_target);
10493  }
10494 
10495  static constexpr OpProperties kProperties = OpProperties::JSCall();
10496 
10497  Input& closure() { return input(kClosureIndex); }
10498  const Input& closure() const { return input(kClosureIndex); }
10499  Input& context() { return input(kContextIndex); }
10500  const Input& context() const { return input(kContextIndex); }
10501  Input& receiver() { return input(kReceiverIndex); }
10502  const Input& receiver() const { return input(kReceiverIndex); }
10503  Input& new_target() { return input(kNewTargetIndex); }
10504  const Input& new_target() const { return input(kNewTargetIndex); }
10505  int num_args() const { return input_count() - kFixedInputCount; }
10506  Input& arg(int i) { return input(i + kFixedInputCount); }
10507  void set_arg(int i, ValueNode* node) {
10508  set_input(i + kFixedInputCount, node);
10509  }
10510  auto args() {
10512  std::make_reverse_iterator(&arg(-1)),
10513  std::make_reverse_iterator(&arg(num_args() - 1)));
10514  }
10515 
10516  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10517 #ifdef V8_COMPRESS_POINTERS
10518  void MarkTaggedInputsAsDecompressing();
10519 #endif
10520  int MaxCallStackArgs() const;
10523  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10524 
10525  private:
10527 };
10528 
10529 class CallKnownJSFunction : public ValueNodeT<CallKnownJSFunction> {
10531 
10532  public:
10533  static constexpr int kClosureIndex = 0;
10534  static constexpr int kContextIndex = 1;
10535  static constexpr int kReceiverIndex = 2;
10536  static constexpr int kNewTargetIndex = 3;
10537  static constexpr int kFixedInputCount = 4;
10538 
10539  // We need enough inputs to have these fixed inputs plus the maximum arguments
10540  // to a function call.
10541  static_assert(kMaxInputs >= kFixedInputCount + Code::kMaxArguments);
10542 
10543  // This ctor is used when for variable input counts.
10544  // Inputs must be initialized manually.
10545  inline CallKnownJSFunction(
10546  uint64_t bitfield,
10547 #ifdef V8_ENABLE_LEAPTIERING
10548  JSDispatchHandle dispatch_handle,
10549 #endif
10550  compiler::SharedFunctionInfoRef shared_function_info, ValueNode* closure,
10551  ValueNode* context, ValueNode* receiver, ValueNode* new_target);
10552 
10553  static constexpr OpProperties kProperties = OpProperties::JSCall();
10554 
10555  Input& closure() { return input(kClosureIndex); }
10556  const Input& closure() const { return input(kClosureIndex); }
10557  Input& context() { return input(kContextIndex); }
10558  const Input& context() const { return input(kContextIndex); }
10559  Input& receiver() { return input(kReceiverIndex); }
10560  const Input& receiver() const { return input(kReceiverIndex); }
10561  Input& new_target() { return input(kNewTargetIndex); }
10562  const Input& new_target() const { return input(kNewTargetIndex); }
10563  int num_args() const { return input_count() - kFixedInputCount; }
10564  Input& arg(int i) { return input(i + kFixedInputCount); }
10565  void set_arg(int i, ValueNode* node) {
10566  set_input(i + kFixedInputCount, node);
10567  }
10568  auto args() {
10570  std::make_reverse_iterator(&arg(-1)),
10571  std::make_reverse_iterator(&arg(num_args() - 1)));
10572  }
10573 
10575  return shared_function_info_;
10576  }
10577 
10578  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10579 #ifdef V8_COMPRESS_POINTERS
10580  void MarkTaggedInputsAsDecompressing();
10581 #endif
10582  int MaxCallStackArgs() const;
10585  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10586 
10587  int expected_parameter_count() const { return expected_parameter_count_; }
10588 
10589  private:
10590 #ifdef V8_ENABLE_LEAPTIERING
10591  JSDispatchHandle dispatch_handle_;
10592 #endif
10594  // Cache the expected parameter count so that we can access it in
10595  // MaxCallStackArgs without needing to unpark the local isolate.
10597 };
10598 
10599 class CallKnownApiFunction : public ValueNodeT<CallKnownApiFunction> {
10601 
10602  public:
10603  enum Mode {
10604  // Use Builtin::kCallApiCallbackOptimizedNoProfiling.
10606  // Inline API call sequence into the generated code.
10608  // Use Builtin::kCallApiCallbackOptimized.
10610  };
10611 
10612  static constexpr int kContextIndex = 0;
10613  static constexpr int kReceiverIndex = 1;
10614  static constexpr int kFixedInputCount = 2;
10615 
10616  // We need enough inputs to have these fixed inputs plus the maximum arguments
10617  // to a function call.
10618  static_assert(kMaxInputs >= kFixedInputCount + Code::kMaxArguments);
10619 
10620  // This ctor is used when for variable input counts.
10621  // Inputs must be initialized manually.
10622  CallKnownApiFunction(uint64_t bitfield, Mode mode,
10623  compiler::FunctionTemplateInfoRef function_template_info,
10624  ValueNode* context, ValueNode* receiver)
10625  : Base(bitfield | ModeField::encode(mode)),
10626  function_template_info_(function_template_info) {
10627  set_input(kContextIndex, context);
10628  set_input(kReceiverIndex, receiver);
10629  }
10630 
10631  // TODO(ishell): introduce JSApiCall() which will take C++ ABI into account
10632  // when deciding which registers to splill.
10633  static constexpr OpProperties kProperties = OpProperties::JSCall();
10634 
10635  // Input& closure() { return input(kClosureIndex); }
10636  // const Input& closure() const { return input(kClosureIndex); }
10637  Input& context() { return input(kContextIndex); }
10638  const Input& context() const { return input(kContextIndex); }
10639  Input& receiver() { return input(kReceiverIndex); }
10640  const Input& receiver() const { return input(kReceiverIndex); }
10641  int num_args() const { return input_count() - kFixedInputCount; }
10642  Input& arg(int i) { return input(i + kFixedInputCount); }
10643  void set_arg(int i, ValueNode* node) {
10644  set_input(i + kFixedInputCount, node);
10645  }
10646  auto args() {
10648  std::make_reverse_iterator(&arg(-1)),
10649  std::make_reverse_iterator(&arg(num_args() - 1)));
10650  }
10651 
10652  Mode mode() const { return ModeField::decode(bitfield()); }
10653 
10655  return function_template_info_;
10656  }
10657 
10658  bool inline_builtin() const { return mode() == kNoProfilingInlined; }
10659 
10660  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10661 #ifdef V8_COMPRESS_POINTERS
10662  void MarkTaggedInputsAsDecompressing();
10663 #endif
10664  int MaxCallStackArgs() const;
10667  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10668 
10669  private:
10670  using ModeField = NextBitField<Mode, 2>;
10671 
10673  const ProcessingState& state);
10674 
10676  const compiler::OptionalJSObjectRef api_holder_;
10677 };
10678 
10679 class ConstructWithSpread : public ValueNodeT<ConstructWithSpread> {
10681 
10682  public:
10683  // We assume function and context as fixed inputs.
10684  static constexpr int kFunctionIndex = 0;
10685  static constexpr int kNewTargetIndex = 1;
10686  static constexpr int kContextIndex = 2;
10687  static constexpr int kFixedInputCount = 3;
10688 
10689  // This ctor is used when for variable input counts.
10690  // Inputs must be initialized manually.
10691  ConstructWithSpread(uint64_t bitfield, compiler::FeedbackSource feedback,
10692  ValueNode* function, ValueNode* new_target,
10693  ValueNode* context)
10694  : Base(bitfield), feedback_(feedback) {
10695  set_input(kFunctionIndex, function);
10696  set_input(kNewTargetIndex, new_target);
10697  set_input(kContextIndex, context);
10698  }
10699 
10700  static constexpr OpProperties kProperties = OpProperties::JSCall();
10701 
10702  Input& function() { return input(kFunctionIndex); }
10703  const Input& function() const { return input(kFunctionIndex); }
10704  Input& new_target() { return input(kNewTargetIndex); }
10705  const Input& new_target() const { return input(kNewTargetIndex); }
10706  Input& context() { return input(kContextIndex); }
10707  const Input& context() const { return input(kContextIndex); }
10708  int num_args() const { return input_count() - kFixedInputCount; }
10709  int num_args_no_spread() const {
10710  DCHECK_GT(num_args(), 0);
10711  return num_args() - 1;
10712  }
10713  Input& arg(int i) { return input(i + kFixedInputCount); }
10714  void set_arg(int i, ValueNode* node) {
10715  set_input(i + kFixedInputCount, node);
10716  }
10718  // Spread is the last argument/input.
10719  return input(input_count() - 1);
10720  }
10723  std::make_reverse_iterator(&arg(-1)),
10724  std::make_reverse_iterator(&arg(num_args_no_spread() - 1)));
10725  }
10726  compiler::FeedbackSource feedback() const { return feedback_; }
10727 
10728  void VerifyInputs(MaglevGraphLabeller* graph_labeller) const;
10729 #ifdef V8_COMPRESS_POINTERS
10730  void MarkTaggedInputsAsDecompressing();
10731 #endif
10732  int MaxCallStackArgs() const;
10735  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10736 
10737  private:
10739 };
10740 
10741 class ConvertReceiver : public FixedInputValueNodeT<1, ConvertReceiver> {
10743 
10744  public:
10745  explicit ConvertReceiver(uint64_t bitfield,
10748  : Base(bitfield), native_context_(native_context), mode_(mode) {}
10749 
10750  Input& receiver_input() { return input(0); }
10751 
10752  // The implementation currently calls runtime.
10753  static constexpr OpProperties kProperties = OpProperties::Call() |
10755  OpProperties::NotIdempotent();
10756  static constexpr
10757  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10758 
10759  int MaxCallStackArgs() const;
10762  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10763 
10764  auto options() const { return std::tuple{native_context_, mode_}; }
10765 
10766  compiler::NativeContextRef native_context() const { return native_context_; }
10767  ConvertReceiverMode mode() const { return mode_; }
10768 
10769  private:
10772 };
10773 
10775  : public FixedInputValueNodeT<2, CheckConstructResult> {
10777 
10778  public:
10779  explicit CheckConstructResult(uint64_t bitfield) : Base(bitfield) {}
10780 
10781  Input& construct_result_input() { return input(0); }
10782  Input& implicit_receiver_input() { return input(1); }
10783 
10784  static constexpr typename Base::InputTypes kInputTypes{
10785  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
10786 
10787  int MaxCallStackArgs() const;
10790  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10791 };
10792 
10794  : public FixedInputValueNodeT<1, CheckDerivedConstructResult> {
10796 
10797  public:
10798  explicit CheckDerivedConstructResult(uint64_t bitfield) : Base(bitfield) {}
10799 
10800  Input& construct_result_input() { return input(0); }
10801 
10802  static constexpr OpProperties kProperties = OpProperties::CanThrow() |
10804  OpProperties::DeferredCall();
10805  static constexpr
10806  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10807 
10809 
10810  int MaxCallStackArgs() const;
10813  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10814 };
10815 
10817  : public FixedInputNodeT<1, CheckJSReceiverOrNullOrUndefined> {
10819 
10820  public:
10821  explicit CheckJSReceiverOrNullOrUndefined(uint64_t bitfield,
10822  CheckType check_type)
10823  : Base(CheckTypeBitField::update(bitfield, check_type)) {}
10824 
10825  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
10826  static constexpr
10827  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10828 
10829  Input& object_input() { return input(0); }
10830  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
10831 
10834  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10835 
10836  auto options() const { return std::tuple{check_type()}; }
10837 
10838  private:
10839  using CheckTypeBitField = NextBitField<CheckType, 1>;
10840 };
10841 
10842 class CheckNotHole : public FixedInputNodeT<1, CheckNotHole> {
10844 
10845  public:
10846  explicit CheckNotHole(uint64_t bitfield) : Base(bitfield) {}
10847 
10848  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
10849  static constexpr
10850  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10851 
10852  Input& object_input() { return input(0); }
10853 
10856  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10857 };
10858 
10860  : public FixedInputNodeT<1, CheckHoleyFloat64NotHole> {
10862 
10863  public:
10864  explicit CheckHoleyFloat64NotHole(uint64_t bitfield) : Base(bitfield) {}
10865 
10866  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
10867  static constexpr
10868  typename Base::InputTypes kInputTypes{ValueRepresentation::kHoleyFloat64};
10869 
10870  Input& float64_input() { return input(0); }
10871 
10874  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10875 };
10876 
10878  : public FixedInputValueNodeT<1, ConvertHoleToUndefined> {
10880 
10881  public:
10882  explicit ConvertHoleToUndefined(uint64_t bitfield) : Base(bitfield) {}
10883 
10884  static constexpr
10885  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10886 
10887  Input& object_input() { return input(0); }
10888 
10891  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10892 };
10893 
10895  : public FixedInputNodeT<0, HandleNoHeapWritesInterrupt> {
10897 
10898  public:
10899  explicit HandleNoHeapWritesInterrupt(uint64_t bitfield) : Base(bitfield) {}
10900 
10901  static constexpr OpProperties kProperties = OpProperties::DeferredCall() |
10902  OpProperties::LazyDeopt() |
10903  OpProperties::NotIdempotent();
10904 
10907  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10908  int MaxCallStackArgs() const { return 0; }
10909 };
10910 
10912  : public FixedInputNodeT<1, ReduceInterruptBudgetForLoop> {
10914 
10915  public:
10916  explicit ReduceInterruptBudgetForLoop(uint64_t bitfield, int amount)
10917  : Base(bitfield), amount_(amount) {
10918  DCHECK_GT(amount, 0);
10919  }
10920 
10921  static constexpr
10922  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10923 
10924  static constexpr OpProperties kProperties =
10925  OpProperties::DeferredCall() | OpProperties::CanAllocate() |
10926  OpProperties::LazyDeopt() | OpProperties::NotIdempotent();
10927 
10928  int amount() const { return amount_; }
10929 
10930  Input& feedback_cell() { return input(0); }
10931 
10932  int MaxCallStackArgs() const;
10933  void SetValueLocationConstraints();
10934  void GenerateCode(MaglevAssembler*, const ProcessingState&);
10935  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10936 
10937  private:
10938  const int amount_;
10939 };
10940 
10942  : public FixedInputNodeT<1, ReduceInterruptBudgetForReturn> {
10944 
10945  public:
10946  explicit ReduceInterruptBudgetForReturn(uint64_t bitfield, int amount)
10947  : Base(bitfield), amount_(amount) {
10948  DCHECK_GT(amount, 0);
10949  }
10950 
10951  static constexpr
10952  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10953 
10954  static constexpr OpProperties kProperties =
10955  OpProperties::DeferredCall() | OpProperties::NotIdempotent();
10956 
10957  int amount() const { return amount_; }
10958 
10959  Input& feedback_cell() { return input(0); }
10960 
10961  int MaxCallStackArgs() const;
10962  void SetValueLocationConstraints();
10963  void GenerateCode(MaglevAssembler*, const ProcessingState&);
10964  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
10965 
10966  private:
10967  const int amount_;
10968 };
10969 
10971  : public FixedInputNodeT<1, ThrowReferenceErrorIfHole> {
10973 
10974  public:
10975  explicit ThrowReferenceErrorIfHole(uint64_t bitfield,
10976  const compiler::NameRef name)
10977  : Base(bitfield), name_(name) {}
10978 
10979  static constexpr OpProperties kProperties =
10980  OpProperties::CanThrow() | OpProperties::DeferredCall();
10981  static constexpr
10982  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
10983 
10984  compiler::NameRef name() const { return name_; }
10985 
10986  Input& value() { return Node::input(0); }
10987 
10988  int MaxCallStackArgs() const;
10991  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
10992 
10993  auto options() const { return std::tuple{name_}; }
10994 
10995  private:
10997 };
10998 
11000  : public FixedInputNodeT<1, ThrowSuperNotCalledIfHole> {
11002 
11003  public:
11004  explicit ThrowSuperNotCalledIfHole(uint64_t bitfield) : Base(bitfield) {}
11005 
11006  static constexpr OpProperties kProperties =
11007  OpProperties::CanThrow() | OpProperties::DeferredCall();
11008  static constexpr
11009  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11010 
11011  Input& value() { return Node::input(0); }
11012 
11013  int MaxCallStackArgs() const;
11016  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11017 };
11018 
11020  : public FixedInputNodeT<1, ThrowSuperAlreadyCalledIfNotHole> {
11022 
11023  public:
11024  explicit ThrowSuperAlreadyCalledIfNotHole(uint64_t bitfield)
11025  : Base(bitfield) {}
11026 
11027  static constexpr OpProperties kProperties =
11028  OpProperties::CanThrow() | OpProperties::DeferredCall();
11029  static constexpr
11030  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11031 
11032  Input& value() { return Node::input(0); }
11033 
11034  int MaxCallStackArgs() const;
11037  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11038 };
11039 
11040 class ThrowIfNotCallable : public FixedInputNodeT<1, ThrowIfNotCallable> {
11042 
11043  public:
11044  explicit ThrowIfNotCallable(uint64_t bitfield) : Base(bitfield) {}
11045 
11046  static constexpr OpProperties kProperties =
11047  OpProperties::CanThrow() | OpProperties::DeferredCall();
11048  static constexpr
11049  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11050 
11051  Input& value() { return Node::input(0); }
11052 
11053  int MaxCallStackArgs() const;
11056  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11057 };
11058 
11060  : public FixedInputNodeT<2, ThrowIfNotSuperConstructor> {
11062 
11063  public:
11064  explicit ThrowIfNotSuperConstructor(uint64_t bitfield) : Base(bitfield) {}
11065 
11066  static constexpr OpProperties kProperties =
11067  OpProperties::CanThrow() | OpProperties::DeferredCall();
11068  static constexpr typename Base::InputTypes kInputTypes{
11069  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
11070 
11071  Input& constructor() { return Node::input(0); }
11072  Input& function() { return Node::input(1); }
11073 
11074  int MaxCallStackArgs() const;
11077  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11078 };
11079 
11081  : public FixedInputValueNodeT<2, TransitionElementsKind> {
11083 
11084  public:
11086  uint64_t bitfield, const ZoneVector<compiler::MapRef>& transition_sources,
11087  compiler::MapRef transition_target)
11088  : Base(bitfield),
11089  transition_sources_(transition_sources),
11090  transition_target_(transition_target) {}
11091 
11092  // TODO(leszeks): Special case the case where all transitions are fast.
11093  static constexpr OpProperties kProperties =
11094  OpProperties::AnySideEffects() | OpProperties::DeferredCall();
11095  static constexpr typename Base::InputTypes kInputTypes{
11096  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
11097 
11098  Input& object_input() { return input(0); }
11099  Input& map_input() { return input(1); }
11100 
11101  int MaxCallStackArgs() const;
11104  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11105 
11107  return transition_sources_;
11108  }
11110  return transition_target_;
11111  }
11112 
11113  private:
11116 };
11117 
11119  : public FixedInputNodeT<2, TransitionElementsKindOrCheckMap> {
11121 
11122  public:
11124  uint64_t bitfield, const ZoneVector<compiler::MapRef>& transition_sources,
11125  compiler::MapRef transition_target)
11126  : Base(bitfield),
11127  transition_sources_(transition_sources),
11128  transition_target_(transition_target) {}
11129 
11130  // TODO(leszeks): Special case the case where all transitions are fast.
11131  static constexpr OpProperties kProperties = OpProperties::AnySideEffects() |
11132  OpProperties::DeferredCall() |
11133  OpProperties::EagerDeopt();
11134  static constexpr typename Base::InputTypes kInputTypes{
11135  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
11136 
11137  Input& object_input() { return Node::input(0); }
11138  Input& map_input() { return Node::input(1); }
11139 
11140  int MaxCallStackArgs() const;
11143  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11144 
11146  return transition_sources_;
11147  }
11149  return transition_target_;
11150  }
11151 
11152  private:
11155 };
11156 
11158  : public FixedInputValueNodeT<0, GetContinuationPreservedEmbedderData> {
11160 
11161  public:
11162  explicit GetContinuationPreservedEmbedderData(uint64_t bitfield)
11163  : Base(bitfield) {}
11164 
11167  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11168 
11169  static constexpr OpProperties kProperties =
11170  OpProperties::CanRead() | OpProperties::TaggedValue();
11171 };
11172 
11174  : public FixedInputNodeT<1, SetContinuationPreservedEmbedderData> {
11176 
11177  public:
11178  explicit SetContinuationPreservedEmbedderData(uint64_t bitfield)
11179  : Base(bitfield) {}
11180 
11181  static constexpr
11182  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11183 
11184  Input& data_input() { return input(0); }
11185 
11188  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11189 
11190  static constexpr OpProperties kProperties = OpProperties::CanWrite();
11191 };
11192 
11193 class ControlNode : public NodeBase {
11194  public:
11195  // A "hole" in control flow is a control node that unconditionally interrupts
11196  // linear control flow (either by jumping or by exiting).
11197  //
11198  // A "post-dominating" hole is a hole that is guaranteed to be be reached in
11199  // control flow after this node (i.e. it is a hole that is a post-dominator
11200  // of this node).
11202  return next_post_dominating_hole_;
11203  }
11205  DCHECK_IMPLIES(node != nullptr, node->Is<UnconditionalControlNode>() ||
11206  node->Is<TerminalControlNode>() ||
11207  node->Is<Switch>());
11208  next_post_dominating_hole_ = node;
11209  }
11210 
11211  protected:
11212  using NodeBase::NodeBase;
11213 
11214  private:
11215  ControlNode* next_post_dominating_hole_ = nullptr;
11216 };
11217 
11219  public:
11220  BasicBlock* target() const { return target_.block_ptr(); }
11221  int predecessor_id() const { return predecessor_id_; }
11222  void set_predecessor_id(int id) { predecessor_id_ = id; }
11223 
11224  void set_target(BasicBlock* block) { target_.set_block_ptr(block); }
11225 
11226  protected:
11227  explicit UnconditionalControlNode(uint64_t bitfield,
11228  BasicBlockRef* target_refs)
11229  : ControlNode(bitfield), target_(target_refs) {}
11230  explicit UnconditionalControlNode(uint64_t bitfield, BasicBlock* target)
11231  : ControlNode(bitfield), target_(target) {}
11232 
11233  private:
11235  int predecessor_id_ = 0;
11236 };
11237 
11238 template <class Derived>
11240  : public FixedInputNodeTMixin<0, UnconditionalControlNode, Derived> {
11241  static_assert(IsUnconditionalControlNode(NodeBase::opcode_of<Derived>));
11242 
11243  protected:
11244  explicit UnconditionalControlNodeT(uint64_t bitfield,
11245  BasicBlockRef* target_refs)
11247  bitfield, target_refs) {}
11248  explicit UnconditionalControlNodeT(uint64_t bitfield, BasicBlock* target)
11249  : FixedInputNodeTMixin<0, UnconditionalControlNode, Derived>(bitfield,
11250  target) {}
11251 };
11252 
11254  public:
11255  explicit ConditionalControlNode(uint64_t bitfield) : ControlNode(bitfield) {}
11256 };
11257 
11259  public:
11260  BranchControlNode(uint64_t bitfield, BasicBlockRef* if_true_refs,
11261  BasicBlockRef* if_false_refs)
11262  : ConditionalControlNode(bitfield),
11263  if_true_(if_true_refs),
11264  if_false_(if_false_refs) {}
11265 
11266  BasicBlock* if_true() const { return if_true_.block_ptr(); }
11267  BasicBlock* if_false() const { return if_false_.block_ptr(); }
11268 
11269  void set_if_true(BasicBlock* block) { if_true_.set_block_ptr(block); }
11270  void set_if_false(BasicBlock* block) { if_false_.set_block_ptr(block); }
11271 
11272  private:
11275 };
11276 
11278  protected:
11279  explicit TerminalControlNode(uint64_t bitfield) : ControlNode(bitfield) {}
11280 };
11281 
11282 template <size_t InputCount, class Derived>
11284  : public FixedInputNodeTMixin<InputCount, TerminalControlNode, Derived> {
11285  static_assert(IsTerminalControlNode(NodeBase::opcode_of<Derived>));
11286 
11287  protected:
11288  explicit TerminalControlNodeT(uint64_t bitfield)
11289  : FixedInputNodeTMixin<InputCount, TerminalControlNode, Derived>(
11290  bitfield) {}
11291 };
11292 
11293 template <size_t InputCount, class Derived>
11295  : public FixedInputNodeTMixin<InputCount, BranchControlNode, Derived> {
11296  static_assert(IsBranchControlNode(NodeBase::opcode_of<Derived>));
11297 
11298  protected:
11299  explicit BranchControlNodeT(uint64_t bitfield, BasicBlockRef* if_true_refs,
11300  BasicBlockRef* if_false_refs)
11301  : FixedInputNodeTMixin<InputCount, BranchControlNode, Derived>(
11302  bitfield, if_true_refs, if_false_refs) {}
11303 };
11304 
11305 class Jump : public UnconditionalControlNodeT<Jump> {
11307 
11308  public:
11309  Jump(uint64_t bitfield, BasicBlockRef* target_refs)
11310  : Base(bitfield, target_refs) {}
11311 
11314  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11315 };
11316 
11317 // TODO(olivf): Unify implementation with Jump.
11318 class CheckpointedJump : public UnconditionalControlNodeT<CheckpointedJump> {
11320 
11321  public:
11322  CheckpointedJump(uint64_t bitfield, BasicBlockRef* target_refs)
11323  : Base(bitfield, target_refs) {}
11324 
11325  static constexpr OpProperties kProperties =
11326  OpProperties::DeoptCheckpoint() | Base::kProperties;
11327 
11330  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11331 };
11332 
11333 class JumpLoop : public UnconditionalControlNodeT<JumpLoop> {
11335 
11336  public:
11337  explicit JumpLoop(uint64_t bitfield, BasicBlock* target)
11338  : Base(bitfield, target) {}
11339 
11340  explicit JumpLoop(uint64_t bitfield, BasicBlockRef* ref)
11341  : Base(bitfield, ref) {}
11342 
11345  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11346 
11347  base::Vector<Input> used_nodes() { return used_node_locations_; }
11349  used_node_locations_ = locations;
11350  }
11351 
11352  private:
11354 };
11355 
11356 class Abort : public TerminalControlNodeT<0, Abort> {
11358 
11359  public:
11360  explicit Abort(uint64_t bitfield, AbortReason reason)
11361  : Base(bitfield), reason_(reason) {
11362  DCHECK_EQ(NodeBase::opcode(), opcode_of<Abort>);
11363  }
11364 
11365  static constexpr OpProperties kProperties = OpProperties::Call();
11366 
11367  AbortReason reason() const { return reason_; }
11368 
11369  int MaxCallStackArgs() const;
11372  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11373 
11374  private:
11376 };
11377 
11378 class Return : public TerminalControlNodeT<1, Return> {
11380 
11381  public:
11382  explicit Return(uint64_t bitfield) : Base(bitfield) {
11383  DCHECK_EQ(NodeBase::opcode(), opcode_of<Return>);
11384  }
11385 
11386  static constexpr
11387  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11388 
11389  Input& value_input() { return input(0); }
11390 
11391  void SetValueLocationConstraints();
11392  void GenerateCode(MaglevAssembler*, const ProcessingState&);
11393  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11394 };
11395 
11396 class Deopt : public TerminalControlNodeT<0, Deopt> {
11398 
11399  public:
11400  explicit Deopt(uint64_t bitfield, DeoptimizeReason reason)
11401  : Base(bitfield | ReasonField::encode(reason)) {
11402  DCHECK_EQ(NodeBase::opcode(), opcode_of<Deopt>);
11403  }
11404 
11405  static constexpr OpProperties kProperties = OpProperties::EagerDeopt();
11406 
11409  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11410 
11412 };
11413 
11414 class Switch : public FixedInputNodeTMixin<1, ConditionalControlNode, Switch> {
11416 
11417  public:
11418  explicit Switch(uint64_t bitfield, int value_base, BasicBlockRef* targets,
11419  int size)
11420  : Base(bitfield),
11421  value_base_(value_base),
11422  targets_(targets),
11423  size_(size),
11424  fallthrough_() {}
11425 
11426  explicit Switch(uint64_t bitfield, int value_base, BasicBlockRef* targets,
11427  int size, BasicBlockRef* fallthrough)
11428  : Base(bitfield),
11429  value_base_(value_base),
11430  targets_(targets),
11431  size_(size),
11432  fallthrough_(fallthrough) {}
11433 
11434  static constexpr
11435  typename Base::InputTypes kInputTypes{ValueRepresentation::kInt32};
11436 
11437  int value_base() const { return value_base_; }
11438  BasicBlockRef* targets() const { return targets_; }
11439  int size() const { return size_; }
11440 
11441  bool has_fallthrough() const { return fallthrough_.has_value(); }
11443  DCHECK(has_fallthrough());
11444  return fallthrough_.value().block_ptr();
11445  }
11446 
11447  void set_fallthrough(BasicBlock* fallthrough) {
11448  DCHECK(has_fallthrough());
11449  fallthrough_.value().set_block_ptr(fallthrough);
11450  }
11451 
11452  Input& value() { return input(0); }
11453 
11456  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11457 
11458  private:
11459  const int value_base_;
11461  const int size_;
11462  std::optional<BasicBlockRef> fallthrough_;
11463 };
11464 
11465 class BranchIfSmi : public BranchControlNodeT<1, BranchIfSmi> {
11467 
11468  public:
11469  explicit BranchIfSmi(uint64_t bitfield, BasicBlockRef* if_true_refs,
11470  BasicBlockRef* if_false_refs)
11471  : Base(bitfield, if_true_refs, if_false_refs) {}
11472 
11473  static constexpr
11474  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11475 
11476  Input& condition_input() { return input(0); }
11477 
11478 #ifdef V8_COMPRESS_POINTERS
11479  void MarkTaggedInputsAsDecompressing() {
11480  // Don't need to decompress values to reference compare.
11481  }
11482 #endif
11483 
11486  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11487 };
11488 
11490  : public BranchControlNodeT<1, BranchIfRootConstant> {
11492 
11493  public:
11494  explicit BranchIfRootConstant(uint64_t bitfield, RootIndex root_index,
11495  BasicBlockRef* if_true_refs,
11496  BasicBlockRef* if_false_refs)
11497  : Base(bitfield, if_true_refs, if_false_refs), root_index_(root_index) {}
11498 
11499  static constexpr
11500  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11501 
11502  RootIndex root_index() { return root_index_; }
11503  Input& condition_input() { return input(0); }
11504 
11505 #ifdef V8_COMPRESS_POINTERS
11506  void MarkTaggedInputsAsDecompressing() {
11507  // Don't need to decompress values to reference compare.
11508  }
11509 #endif
11510 
11513  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11514 
11515  private:
11517 };
11518 
11520  : public BranchControlNodeT<1, BranchIfUndefinedOrNull> {
11522 
11523  public:
11524  explicit BranchIfUndefinedOrNull(uint64_t bitfield,
11525  BasicBlockRef* if_true_refs,
11526  BasicBlockRef* if_false_refs)
11527  : Base(bitfield, if_true_refs, if_false_refs) {}
11528 
11529  static constexpr
11530  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11531 
11532  Input& condition_input() { return input(0); }
11533 
11534 #ifdef V8_COMPRESS_POINTERS
11535  void MarkTaggedInputsAsDecompressing() {
11536  // Don't need to decompress values to reference compare.
11537  }
11538 #endif
11539 
11542  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11543 };
11544 
11546  : public BranchControlNodeT<1, BranchIfUndetectable> {
11548 
11549  public:
11550  explicit BranchIfUndetectable(uint64_t bitfield, CheckType check_type,
11551  BasicBlockRef* if_true_refs,
11552  BasicBlockRef* if_false_refs)
11553  : Base(CheckTypeBitField::update(bitfield, check_type), if_true_refs,
11554  if_false_refs) {}
11555 
11556  static constexpr
11557  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11558 
11559  Input& condition_input() { return input(0); }
11560  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
11561 
11564  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11565 
11566  private:
11567  using CheckTypeBitField = NextBitField<CheckType, 1>;
11568 };
11569 
11570 class BranchIfJSReceiver : public BranchControlNodeT<1, BranchIfJSReceiver> {
11572 
11573  public:
11574  explicit BranchIfJSReceiver(uint64_t bitfield, BasicBlockRef* if_true_refs,
11575  BasicBlockRef* if_false_refs)
11576  : Base(bitfield, if_true_refs, if_false_refs) {}
11577 
11578  static constexpr
11579  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11580 
11581  Input& condition_input() { return input(0); }
11582 
11585  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11586 };
11587 
11589  : public BranchControlNodeT<1, BranchIfToBooleanTrue> {
11591 
11592  public:
11593  explicit BranchIfToBooleanTrue(uint64_t bitfield, CheckType check_type,
11594  BasicBlockRef* if_true_refs,
11595  BasicBlockRef* if_false_refs)
11596  : Base(CheckTypeBitField::update(bitfield, check_type), if_true_refs,
11597  if_false_refs) {}
11598 
11599  static constexpr
11600  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11601 
11602  Input& condition_input() { return input(0); }
11603  CheckType check_type() const { return CheckTypeBitField::decode(bitfield()); }
11604 
11607  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11608 
11609  private:
11610  using CheckTypeBitField = NextBitField<CheckType, 1>;
11611 };
11612 
11614  : public BranchControlNodeT<1, BranchIfInt32ToBooleanTrue> {
11616 
11617  public:
11618  explicit BranchIfInt32ToBooleanTrue(uint64_t bitfield,
11619  BasicBlockRef* if_true_refs,
11620  BasicBlockRef* if_false_refs)
11621  : Base(bitfield, if_true_refs, if_false_refs) {}
11622 
11623  static constexpr
11624  typename Base::InputTypes kInputTypes{ValueRepresentation::kInt32};
11625 
11626  Input& condition_input() { return input(0); }
11627 
11630  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11631 };
11632 
11634  : public BranchControlNodeT<1, BranchIfIntPtrToBooleanTrue> {
11636 
11637  public:
11638  explicit BranchIfIntPtrToBooleanTrue(uint64_t bitfield,
11639  BasicBlockRef* if_true_refs,
11640  BasicBlockRef* if_false_refs)
11641  : Base(bitfield, if_true_refs, if_false_refs) {}
11642 
11643  static constexpr
11645 
11646  Input& condition_input() { return input(0); }
11647 
11650  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11651 };
11652 
11654  : public BranchControlNodeT<1, BranchIfFloat64ToBooleanTrue> {
11656 
11657  public:
11658  explicit BranchIfFloat64ToBooleanTrue(uint64_t bitfield,
11659  BasicBlockRef* if_true_refs,
11660  BasicBlockRef* if_false_refs)
11661  : Base(bitfield, if_true_refs, if_false_refs) {}
11662 
11663  static constexpr
11664  typename Base::InputTypes kInputTypes{ValueRepresentation::kHoleyFloat64};
11665 
11666  Input& condition_input() { return input(0); }
11667 
11670  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11671 };
11672 
11673 #ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
11674 class BranchIfFloat64IsUndefinedOrHole
11675  : public BranchControlNodeT<1, BranchIfFloat64IsUndefinedOrHole> {
11676  using Base = BranchControlNodeT<1, BranchIfFloat64IsUndefinedOrHole>;
11677 
11678  public:
11679  explicit BranchIfFloat64IsUndefinedOrHole(uint64_t bitfield,
11680  BasicBlockRef* if_true_refs,
11681  BasicBlockRef* if_false_refs)
11682  : Base(bitfield, if_true_refs, if_false_refs) {}
11683 
11684  static constexpr
11685  typename Base::InputTypes kInputTypes{ValueRepresentation::kHoleyFloat64};
11686 
11687  Input& condition_input() { return input(0); }
11688 
11689  void SetValueLocationConstraints();
11690  void GenerateCode(MaglevAssembler*, const ProcessingState&);
11691  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11692 };
11693 #endif // V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
11694 
11696  : public BranchControlNodeT<1, BranchIfFloat64IsHole> {
11698 
11699  public:
11700  explicit BranchIfFloat64IsHole(uint64_t bitfield, BasicBlockRef* if_true_refs,
11701  BasicBlockRef* if_false_refs)
11702  : Base(bitfield, if_true_refs, if_false_refs) {}
11703 
11704  static constexpr
11705  typename Base::InputTypes kInputTypes{ValueRepresentation::kHoleyFloat64};
11706 
11707  Input& condition_input() { return input(0); }
11708 
11711  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11712 };
11713 
11715  : public BranchControlNodeT<2, BranchIfInt32Compare> {
11717 
11718  public:
11719  static constexpr int kLeftIndex = 0;
11720  static constexpr int kRightIndex = 1;
11721  Input& left_input() { return NodeBase::input(kLeftIndex); }
11722  Input& right_input() { return NodeBase::input(kRightIndex); }
11723 
11724  explicit BranchIfInt32Compare(uint64_t bitfield, Operation operation,
11725  BasicBlockRef* if_true_refs,
11726  BasicBlockRef* if_false_refs)
11727  : Base(bitfield, if_true_refs, if_false_refs), operation_(operation) {}
11728 
11729  static constexpr typename Base::InputTypes kInputTypes{
11730  ValueRepresentation::kInt32, ValueRepresentation::kInt32};
11731 
11734  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11735 
11736  Operation operation() const { return operation_; }
11737 
11738  private:
11740 };
11741 
11743  : public BranchControlNodeT<2, BranchIfUint32Compare> {
11745 
11746  public:
11747  static constexpr int kLeftIndex = 0;
11748  static constexpr int kRightIndex = 1;
11749  Input& left_input() { return NodeBase::input(kLeftIndex); }
11750  Input& right_input() { return NodeBase::input(kRightIndex); }
11751 
11752  explicit BranchIfUint32Compare(uint64_t bitfield, Operation operation,
11753  BasicBlockRef* if_true_refs,
11754  BasicBlockRef* if_false_refs)
11755  : Base(bitfield, if_true_refs, if_false_refs), operation_(operation) {}
11756 
11757  static constexpr typename Base::InputTypes kInputTypes{
11758  ValueRepresentation::kUint32, ValueRepresentation::kUint32};
11759 
11762  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11763 
11764  Operation operation() const { return operation_; }
11765 
11766  private:
11768 };
11769 
11771  : public BranchControlNodeT<2, BranchIfFloat64Compare> {
11773 
11774  public:
11775  static constexpr int kLeftIndex = 0;
11776  static constexpr int kRightIndex = 1;
11777  Input& left_input() { return NodeBase::input(kLeftIndex); }
11778  Input& right_input() { return NodeBase::input(kRightIndex); }
11779 
11780  explicit BranchIfFloat64Compare(uint64_t bitfield, Operation operation,
11781  BasicBlockRef* if_true_refs,
11782  BasicBlockRef* if_false_refs)
11783  : Base(bitfield, if_true_refs, if_false_refs), operation_(operation) {}
11784 
11785  static constexpr typename Base::InputTypes kInputTypes{
11786  ValueRepresentation::kFloat64, ValueRepresentation::kFloat64};
11787 
11790  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11791 
11792  Operation operation() const { return operation_; }
11793 
11794  private:
11796 };
11797 
11799  : public BranchControlNodeT<2, BranchIfReferenceEqual> {
11801 
11802  public:
11803  static constexpr int kLeftIndex = 0;
11804  static constexpr int kRightIndex = 1;
11805  Input& left_input() { return NodeBase::input(kLeftIndex); }
11806  Input& right_input() { return NodeBase::input(kRightIndex); }
11807 
11808  explicit BranchIfReferenceEqual(uint64_t bitfield,
11809  BasicBlockRef* if_true_refs,
11810  BasicBlockRef* if_false_refs)
11811  : Base(bitfield, if_true_refs, if_false_refs) {}
11812 
11813  static constexpr typename Base::InputTypes kInputTypes{
11814  ValueRepresentation::kTagged, ValueRepresentation::kTagged};
11815 
11816 #ifdef V8_COMPRESS_POINTERS
11817  void MarkTaggedInputsAsDecompressing() {
11818  // Don't need to decompress values to reference compare.
11819  }
11820 #endif
11821 
11824  void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
11825 };
11826 
11827 class BranchIfTypeOf : public BranchControlNodeT<1, BranchIfTypeOf> {
11829 
11830  public:
11831  static constexpr int kValueIndex = 0;
11832  Input& value_input() { return NodeBase::input(kValueIndex); }
11833 
11834  explicit BranchIfTypeOf(uint64_t bitfield,
11836  BasicBlockRef* if_true_refs,
11837  BasicBlockRef* if_false_refs)
11838  : Base(bitfield, if_true_refs, if_false_refs), literal_(literal) {}
11839 
11840  static constexpr
11841  typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
11842 
11845  void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
11846 
11847  private:
11849 };
11850 
11852  switch (opcode) {
11853 #define CASE(op) \
11854  case Opcode::k##op: \
11855  return op::kProperties;
11857 #undef CASE
11858  }
11859 }
11860 
11861 template <typename Function>
11862 inline void NodeBase::ForAllInputsInRegallocAssignmentOrder(Function&& f) {
11863  auto iterate_inputs = [&](InputAllocationPolicy category) {
11864  for (Input& input : *this) {
11865  switch (compiler::UnallocatedOperand::cast(input.operand())
11866  .extended_policy()) {
11867  case compiler::UnallocatedOperand::MUST_HAVE_REGISTER:
11868  if (category == InputAllocationPolicy::kArbitraryRegister)
11869  f(category, &input);
11870  break;
11871 
11872  case compiler::UnallocatedOperand::REGISTER_OR_SLOT_OR_CONSTANT:
11873  if (category == InputAllocationPolicy::kAny) f(category, &input);
11874  break;
11875 
11876  case compiler::UnallocatedOperand::FIXED_REGISTER:
11877  case compiler::UnallocatedOperand::FIXED_FP_REGISTER:
11878  if (category == InputAllocationPolicy::kFixedRegister)
11879  f(category, &input);
11880  break;
11881 
11882  case compiler::UnallocatedOperand::REGISTER_OR_SLOT:
11883  case compiler::UnallocatedOperand::SAME_AS_INPUT:
11885  case compiler::UnallocatedOperand::MUST_HAVE_SLOT:
11886  UNREACHABLE();
11887  }
11888  }
11889  };
11890 
11891  iterate_inputs(InputAllocationPolicy::kFixedRegister);
11892  iterate_inputs(InputAllocationPolicy::kArbitraryRegister);
11893  iterate_inputs(InputAllocationPolicy::kAny);
11894 }
11895 
11896 } // namespace maglev
11897 } // namespace internal
11898 } // namespace v8
11899 
11900 #endif // V8_MAGLEV_MAGLEV_IR_H_
#define T
#define CASE(Name,...)
#define SBXCHECK_LT(lhs, rhs)
Definition: check.h:59
#define SLOW_DCHECK(condition)
Definition: checks.h:21
A JavaScript function object (ECMA-262, 15.3).
Definition: v8-function.h:27
A JavaScript value representing a 32-bit signed integer.
Definition: v8-primitive.h:887
A JavaScript value representing a 32-bit unsigned integer.
Definition: v8-primitive.h:905
static constexpr U kMax
Definition: bit-field.h:44
static constexpr int kLastUsedBit
Definition: bit-field.h:42
static constexpr T decode(U value)
Definition: bit-field.h:66
static constexpr bool is_valid(T value)
Definition: bit-field.h:50
static constexpr U encode(T value)
Definition: bit-field.h:55
static constexpr U kMask
Definition: bit-field.h:41
static constexpr U update(U previous, T value)
Definition: bit-field.h:61
static constexpr int kShift
Definition: bit-field.h:39
constexpr const auto & get() const
static BytecodeOffset GetContinuationBytecodeOffset(Builtin builtin)
Definition: builtins.cc:97
static constexpr BytecodeOffset None()
Definition: utils.h:679
bool is_nan() const
Definition: boxed-float.h:101
double get_scalar() const
Definition: boxed-float.h:95
constexpr static MachineRepresentation PointerRepresentation()
Definition: machine-type.h:169
static V8_EXPORT_PRIVATE bool BooleanValue(Tagged< Object > obj, IsolateT *isolate)
constexpr RegisterT first() const
Definition: reglist-base.h:111
constexpr void set(RegisterT reg)
Definition: reglist-base.h:47
constexpr bool has(RegisterT reg) const
Definition: reglist-base.h:57
constexpr void clear(RegisterT reg)
Definition: reglist-base.h:52
constexpr unsigned Count() const
Definition: reglist-base.h:66
constexpr int8_t code() const
Definition: register-base.h:43
static constexpr bool IsValid(T value) requires(std
Definition: smi.h:75
static constexpr Tagged< Smi > FromInt(int value)
Definition: smi.h:38
static constexpr bool IsValid(intptr_t value)
Definition: tagged-index.h:46
T * AllocateArray(size_t length)
Definition: zone.h:121
void * Allocate(size_t size)
Definition: zone.h:55
IndirectHandle< HeapObject > object() const
static LocationOperand * cast(InstructionOperand *op)
Definition: instruction.h:599
DoubleRegister GetDoubleRegister() const
Definition: instruction.h:533
bool IsNullMap(JSHeapBroker *broker) const
Definition: heap-refs.cc:1149
bool IsBooleanMap(JSHeapBroker *broker) const
Definition: heap-refs.cc:1145
bool IsUndefinedMap(JSHeapBroker *broker) const
Definition: heap-refs.cc:1153
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const AbortReason reason_
Definition: maglev-ir.h:11375
Abort(uint64_t bitfield, AbortReason reason)
Definition: maglev-ir.h:11360
AbortReason reason() const
Definition: maglev-ir.h:11367
AbstractLoadTaggedField(uint64_t bitfield, const int offset)
Definition: maglev-ir.h:8111
void GenerateCode(MaglevAssembler *, const ProcessingState &)
AllocateElementsArray(uint64_t bitfield, AllocationType allocation_type)
Definition: maglev-ir.h:6563
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:6579
InlinedAllocation::List allocation_list_
Definition: maglev-ir.h:6489
InlinedAllocation::List & allocation_list()
Definition: maglev-ir.h:6468
AllocationType allocation_type() const
Definition: maglev-ir.h:6464
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void Add(InlinedAllocation *alloc)
Definition: maglev-ir.h:6470
AllocationBlock(uint64_t bitfield, AllocationType allocation_type)
Definition: maglev-ir.h:6452
bool elided_write_barriers_depend_on_type() const
Definition: maglev-ir.h:6477
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:6546
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ArgumentsElements(uint64_t bitfield, CreateArgumentsType type, int formal_parameter_count)
Definition: maglev-ir.h:6528
CreateArgumentsType type() const
Definition: maglev-ir.h:6548
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:6502
AssertCondition condition() const
Definition: maglev-ir.h:6782
AbortReason reason() const
Definition: maglev-ir.h:6783
AssertInt32(uint64_t bitfield, AssertCondition condition, AbortReason reason)
Definition: maglev-ir.h:6766
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void Bind(BasicBlock *block)
Definition: maglev-ir.h:1167
void set_block_ptr(BasicBlock *block)
Definition: maglev-ir.h:1182
BasicBlockRef(const BasicBlockRef &)=delete
BasicBlockRef & operator=(BasicBlockRef &&)=delete
BasicBlockRef * next_ref() const
Definition: maglev-ir.h:1187
BasicBlockRef(BasicBlockRef &&)=delete
BasicBlockRef(BasicBlock *block)
Definition: maglev-ir.h:1111
BasicBlockRef * SetToBlockAndReturnNext(BasicBlock *block)
Definition: maglev-ir.h:1134
BasicBlockRef * MoveToRefList(BasicBlockRef *ref_list_head)
Definition: maglev-ir.h:1157
BasicBlockRef(BasicBlockRef *ref_list_head)
Definition: maglev-ir.h:1126
BasicBlock * block_ptr() const
Definition: maglev-ir.h:1177
BasicBlockRef & operator=(const BasicBlockRef &)=delete
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3112
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3111
BinaryWithFeedbackNode(uint64_t bitfield, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:3122
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:3119
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3128
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:3130
BranchControlNodeT(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11299
void set_if_true(BasicBlock *block)
Definition: maglev-ir.h:11269
void set_if_false(BasicBlock *block)
Definition: maglev-ir.h:11270
BranchControlNode(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11260
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfFloat64Compare(uint64_t bitfield, Operation operation, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11780
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11711
BranchIfFloat64IsHole(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11700
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11670
BranchIfFloat64ToBooleanTrue(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11658
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfInt32Compare(uint64_t bitfield, Operation operation, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11724
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfInt32ToBooleanTrue(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11618
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11630
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11650
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfIntPtrToBooleanTrue(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11638
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11585
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfJSReceiver(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11574
BranchIfReferenceEqual(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11808
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11824
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfRootConstant(uint64_t bitfield, RootIndex root_index, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11494
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11486
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfSmi(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11469
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11607
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:11610
BranchIfToBooleanTrue(uint64_t bitfield, CheckType check_type, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11593
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfTypeOf(uint64_t bitfield, interpreter::TestTypeOfFlags::LiteralFlag literal, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11834
interpreter::TestTypeOfFlags::LiteralFlag literal_
Definition: maglev-ir.h:11848
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
BranchIfUint32Compare(uint64_t bitfield, Operation operation, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11752
BranchIfUndefinedOrNull(uint64_t bitfield, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11524
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11542
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11564
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:11567
BranchIfUndetectable(uint64_t bitfield, CheckType check_type, BasicBlockRef *if_true_refs, BasicBlockRef *if_false_refs)
Definition: maglev-ir.h:11550
base::Vector< ValueNode * > parameters() const
Definition: maglev-ir.h:1726
const BuiltinContinuationFrameData & data() const
Definition: maglev-ir.h:1738
BuiltinContinuationFrameData & data()
Definition: maglev-ir.h:1735
BuiltinContinuationDeoptFrame(Builtin builtin_id, base::Vector< ValueNode * > parameters, ValueNode *context, compiler::OptionalJSFunctionRef maybe_js_target, DeoptFrame *parent)
Definition: maglev-ir.h:1716
compiler::JSFunctionRef javascript_target() const
Definition: maglev-ir.h:1730
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7788
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7725
BuiltinStringPrototypeCharCodeOrCodePointAt(uint64_t bitfield, Mode mode)
Definition: maglev-ir.h:7740
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PushFeedbackAndArguments(MaglevAssembler *)
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:10137
CallBuiltin(uint64_t bitfield, Builtin builtin, ValueNode *context)
Definition: maglev-ir.h:10126
FeedbackSlotType slot_type() const
Definition: maglev-ir.h:10141
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10192
void PassFeedbackSlotInRegister(MaglevAssembler *)
void set_feedback(compiler::FeedbackSource const &feedback, FeedbackSlotType slot_type)
Definition: maglev-ir.h:10145
CallBuiltin(uint64_t bitfield, Builtin builtin)
Definition: maglev-ir.h:10118
void PushArguments(MaglevAssembler *masm, Args... extra_args)
std::optional< compiler::FeedbackSource > feedback_
Definition: maglev-ir.h:10214
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const Input & new_target() const
Definition: maglev-ir.h:10249
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10255
CallCPPBuiltin(uint64_t bitfield, Builtin builtin, ValueNode *target, ValueNode *new_target, ValueNode *context)
Definition: maglev-ir.h:10230
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10307
Call::TargetType target_type() const
Definition: maglev-ir.h:10326
CallForwardVarargs(uint64_t bitfield, ValueNode *function, ValueNode *context, int start_index, Call::TargetType target_type)
Definition: maglev-ir.h:10292
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10643
const compiler::OptionalJSObjectRef api_holder_
Definition: maglev-ir.h:10676
compiler::FunctionTemplateInfoRef function_template_info() const
Definition: maglev-ir.h:10654
void GenerateCallApiCallbackOptimizedInline(MaglevAssembler *masm, const ProcessingState &state)
const compiler::FunctionTemplateInfoRef function_template_info_
Definition: maglev-ir.h:10675
CallKnownApiFunction(uint64_t bitfield, Mode mode, compiler::FunctionTemplateInfoRef function_template_info, ValueNode *context, ValueNode *receiver)
Definition: maglev-ir.h:10622
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::SharedFunctionInfoRef shared_function_info() const
Definition: maglev-ir.h:10574
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10565
const compiler::SharedFunctionInfoRef shared_function_info_
Definition: maglev-ir.h:10593
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Runtime::FunctionId function_id() const
Definition: maglev-ir.h:10351
const Input & context() const
Definition: maglev-ir.h:10354
Runtime::FunctionId function_id_
Definition: maglev-ir.h:10380
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CallRuntime(uint64_t bitfield, Runtime::FunctionId function_id, ValueNode *context)
Definition: maglev-ir.h:10343
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10357
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const Input & new_target() const
Definition: maglev-ir.h:10504
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10507
const Input & receiver() const
Definition: maglev-ir.h:10502
const Input & context() const
Definition: maglev-ir.h:10500
const Input & closure() const
Definition: maglev-ir.h:10498
CallSelf(uint64_t bitfield, int expected_parameter_count, ValueNode *closure, ValueNode *context, ValueNode *receiver, ValueNode *new_target)
Definition: maglev-ir.h:10486
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10467
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10412
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10433
CallWithSpread(uint64_t bitfield, ValueNode *function, ValueNode *context)
Definition: maglev-ir.h:10394
const Input & context() const
Definition: maglev-ir.h:10023
ConvertReceiverMode receiver_mode() const
Definition: maglev-ir.h:10044
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10026
ConvertReceiverMode receiver_mode_
Definition: maglev-ir.h:10048
Call(uint64_t bitfield, ConvertReceiverMode mode, TargetType target_type, ValueNode *function, ValueNode *context)
Definition: maglev-ir.h:10011
void GenerateCode(MaglevAssembler *, const ProcessingState &)
TargetType target_type() const
Definition: maglev-ir.h:10045
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4342
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4345
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4351
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4389
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4383
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4380
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4361
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4370
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4364
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7404
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10790
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10813
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7320
CheckDetectableCallable(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7302
void PrintParams(std::ostream &out, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7315
CheckDynamicValue(uint64_t bitfield, DeoptimizeReason reason)
Definition: maglev-ir.h:7030
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckFloat64SameValue(uint64_t bitfield, Float64 value, DeoptimizeReason reason)
Definition: maglev-ir.h:6966
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7129
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3663
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3671
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3665
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10874
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7191
InstanceType first_instance_type() const
Definition: maglev-ir.h:7187
CheckInstanceType(uint64_t bitfield, CheckType check_type, const InstanceType first_instance_type, const InstanceType last_instance_type)
Definition: maglev-ir.h:7161
InstanceType last_instance_type() const
Definition: maglev-ir.h:7188
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ReasonField::Next< AssertCondition, base::bits::WhichPowerOfTwo< size_t >(base::bits::RoundUpToPowerOfTwo32(kNumAssertConditions))> ConditionField
Definition: maglev-ir.h:7536
CheckInt32Condition(uint64_t bitfield, AssertCondition condition, DeoptimizeReason reason)
Definition: maglev-ir.h:7506
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3611
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3613
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3619
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3647
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3653
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3645
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7427
CheckJSDataViewBounds(uint64_t bitfield, ExternalArrayType element_type)
Definition: maglev-ir.h:7411
ExternalArrayType element_type() const
Definition: maglev-ir.h:7431
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10834
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckJSReceiverOrNullOrUndefined(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:10821
const compiler::ZoneRefSet< Map > maps_
Definition: maglev-ir.h:6895
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckMapsWithAlreadyLoadedMap(uint64_t bitfield, base::Vector< const compiler::MapRef > maps, Zone *zone)
Definition: maglev-ir.h:6874
const compiler::ZoneRefSet< Map > & maps() const
Definition: maglev-ir.h:6883
CheckMapsWithAlreadyLoadedMap(uint64_t bitfield, const compiler::ZoneRefSet< Map > &maps)
Definition: maglev-ir.h:6871
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckMapsWithMigrationAndDeopt(uint64_t bitfield, base::Vector< const compiler::MapRef > maps, CheckType check_type, Zone *zone)
Definition: maglev-ir.h:6834
const compiler::ZoneRefSet< Map > & maps() const
Definition: maglev-ir.h:6848
const compiler::ZoneRefSet< Map > maps_
Definition: maglev-ir.h:6863
CheckMapsWithMigrationAndDeopt(uint64_t bitfield, const compiler::ZoneRefSet< Map > &maps, CheckType check_type)
Definition: maglev-ir.h:6830
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:6862
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckMapsWithMigration(uint64_t bitfield, const compiler::ZoneRefSet< Map > &maps, CheckType check_type)
Definition: maglev-ir.h:7328
const compiler::ZoneRefSet< Map > maps_
Definition: maglev-ir.h:7355
const compiler::ZoneRefSet< Map > & maps() const
Definition: maglev-ir.h:7340
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7354
CheckMaps(uint64_t bitfield, base::Vector< const compiler::MapRef > maps, CheckType check_type, Zone *zone)
Definition: maglev-ir.h:6797
const compiler::ZoneRefSet< Map > maps_
Definition: maglev-ir.h:6822
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:6821
CheckType check_type() const
Definition: maglev-ir.h:6809
const compiler::ZoneRefSet< Map > & maps() const
Definition: maglev-ir.h:6808
CheckMaps(uint64_t bitfield, const compiler::ZoneRefSet< Map > &maps, CheckType check_type)
Definition: maglev-ir.h:6794
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10856
Object::Conversion mode() const
Definition: maglev-ir.h:7096
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckNumber(uint64_t bitfield, Object::Conversion mode)
Definition: maglev-ir.h:7087
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7100
const Object::Conversion mode_
Definition: maglev-ir.h:7105
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7243
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckSeqOneByteString(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7225
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7238
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7080
CheckSmi(uint64_t bitfield)
Definition: maglev-ir.h:7061
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7294
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckStringOrOddball(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7276
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7289
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7269
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7264
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckStringOrStringWrapper(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7251
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7213
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7218
CheckString(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7200
CheckSymbol(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7136
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7149
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7154
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7499
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7480
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3630
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3636
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3628
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckValueEqualsInt32(uint64_t bitfield, int32_t value, DeoptimizeReason reason)
Definition: maglev-ir.h:6937
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckValueEqualsString(uint64_t bitfield, compiler::InternalizedStringRef value, DeoptimizeReason reason)
Definition: maglev-ir.h:6996
const compiler::InternalizedStringRef value_
Definition: maglev-ir.h:7023
compiler::InternalizedStringRef value() const
Definition: maglev-ir.h:7008
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::HeapObjectRef value_
Definition: maglev-ir.h:6930
compiler::HeapObjectRef value() const
Definition: maglev-ir.h:6910
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CheckValue(uint64_t bitfield, const compiler::HeapObjectRef value, DeoptimizeReason reason)
Definition: maglev-ir.h:6902
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4733
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4740
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4729
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4253
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4243
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4247
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4332
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4326
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4322
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4273
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4267
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4263
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7613
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7608
CheckedInternalizedString(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7592
CheckedNumberOrOddballToFloat64(uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
Definition: maglev-ir.h:4640
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4667
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4681
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4677
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4687
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4045
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4054
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4048
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:7642
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7637
CheckedObjectToIndex(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:7621
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3402
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3393
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3395
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3376
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3374
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3383
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3713
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3703
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3707
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4223
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4233
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4225
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3680
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3683
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3689
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3742
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3751
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3745
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3723
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3726
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3732
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3848
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3832
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3836
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4409
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4403
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4559
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4549
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8160
TaggedToFloat64ConversionType conversion_type() const
Definition: maglev-ir.h:4870
NextBitField< TaggedToFloat64ConversionType, 2 > TaggedToFloat64ConversionTypeOffset
Definition: maglev-ir.h:4878
CheckedTruncateNumberOrOddballToInt32(uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
Definition: maglev-ir.h:4854
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4306
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4302
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4312
CheckpointedJump(uint64_t bitfield, BasicBlockRef *target_refs)
Definition: maglev-ir.h:11322
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11330
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9561
ConsStringMap(uint64_t bitfield)
Definition: maglev-ir.h:9542
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ConstantGapMove(uint64_t bitfield, ValueNode *node, compiler::AllocatedOperand target)
Definition: maglev-ir.h:9782
compiler::InstructionOperand source_
Definition: maglev-ir.h:9795
compiler::AllocatedOperand target() const
Definition: maglev-ir.h:9786
compiler::AllocatedOperand target_
Definition: maglev-ir.h:9796
bool IsTheHole(compiler::JSHeapBroker *broker) const
Definition: maglev-ir.h:5593
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:5589
compiler::HeapObjectRef object()
Definition: maglev-ir.h:5601
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7927
const compiler::HeapObjectRef object_
Definition: maglev-ir.h:5609
Constant(uint64_t bitfield, compiler::HeapObjectRef object)
Definition: maglev-ir.h:5586
compiler::HeapObjectRef ref() const
Definition: maglev-ir.h:5606
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1232
const MaglevCompilationUnit & unit() const
Definition: maglev-ir.h:1684
ConstructInvokeStubFrameData & data()
Definition: maglev-ir.h:1692
const ConstructInvokeStubFrameData & data() const
Definition: maglev-ir.h:1695
ConstructInvokeStubDeoptFrame(const MaglevCompilationUnit &unit, SourcePosition source_position, ValueNode *receiver, ValueNode *context, DeoptFrame *parent)
Definition: maglev-ir.h:1676
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:10726
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:10738
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10714
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10735
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ConstructWithSpread(uint64_t bitfield, compiler::FeedbackSource feedback, ValueNode *function, ValueNode *new_target, ValueNode *context)
Definition: maglev-ir.h:10691
void set_arg(int i, ValueNode *node)
Definition: maglev-ir.h:10086
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10104
const Input & context() const
Definition: maglev-ir.h:10083
Construct(uint64_t bitfield, const compiler::FeedbackSource &feedback, ValueNode *function, ValueNode *new_target, ValueNode *context)
Definition: maglev-ir.h:10068
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:10107
const Input & new_target() const
Definition: maglev-ir.h:10081
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:10095
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void set_next_post_dominating_hole(ControlNode *node)
Definition: maglev-ir.h:11204
ControlNode * next_post_dominating_hole() const
Definition: maglev-ir.h:11201
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10891
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10762
const compiler::NativeContextRef native_context_
Definition: maglev-ir.h:10770
compiler::NativeContextRef native_context() const
Definition: maglev-ir.h:10766
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ConvertReceiver(uint64_t bitfield, compiler::NativeContextRef native_context, ConvertReceiverMode mode)
Definition: maglev-ir.h:10745
ConvertReceiverMode mode() const
Definition: maglev-ir.h:10767
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5691
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:5695
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5683
const compiler::HeapObjectRef constant_elements_
Definition: maglev-ir.h:5694
CreateArrayLiteral(uint64_t bitfield, compiler::HeapObjectRef constant_elements, const compiler::FeedbackSource &feedback, int flags)
Definition: maglev-ir.h:5669
compiler::HeapObjectRef constant_elements()
Definition: maglev-ir.h:5678
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:5679
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::SharedFunctionInfoRef shared_function_info_
Definition: maglev-ir.h:6723
CreateClosure(uint64_t bitfield, compiler::SharedFunctionInfoRef shared_function_info, compiler::FeedbackCellRef feedback_cell, bool pretenured)
Definition: maglev-ir.h:6693
const compiler::FeedbackCellRef feedback_cell_
Definition: maglev-ir.h:6724
compiler::FeedbackCellRef feedback_cell() const
Definition: maglev-ir.h:6705
compiler::SharedFunctionInfoRef shared_function_info() const
Definition: maglev-ir.h:6702
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7885
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CreateFastArrayElements(uint64_t bitfield, AllocationType allocation_type)
Definition: maglev-ir.h:7869
compiler::ScopeInfoRef scope_info() const
Definition: maglev-ir.h:6600
const compiler::ScopeInfoRef scope_info_
Definition: maglev-ir.h:6619
void GenerateCode(MaglevAssembler *, const ProcessingState &)
CreateFunctionContext(uint64_t bitfield, compiler::ScopeInfoRef scope_info, uint32_t slot_count, ScopeType scope_type)
Definition: maglev-ir.h:6592
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:5765
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:5749
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5761
compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor()
Definition: maglev-ir.h:5746
CreateObjectLiteral(uint64_t bitfield, compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor, const compiler::FeedbackSource &feedback, int flags)
Definition: maglev-ir.h:5737
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5753
const compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor_
Definition: maglev-ir.h:5764
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:6681
CreateRegExpLiteral(uint64_t bitfield, compiler::StringRef pattern, const compiler::FeedbackSource &feedback, int flags)
Definition: maglev-ir.h:6664
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:6685
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:6670
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5718
CreateShallowArrayLiteral(uint64_t bitfield, compiler::HeapObjectRef constant_elements, const compiler::FeedbackSource &feedback, int flags)
Definition: maglev-ir.h:5704
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:5714
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:5728
const compiler::HeapObjectRef constant_elements_
Definition: maglev-ir.h:5727
compiler::HeapObjectRef constant_elements()
Definition: maglev-ir.h:5713
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5724
compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor()
Definition: maglev-ir.h:5785
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5792
CreateShallowObjectLiteral(uint64_t bitfield, compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor, const compiler::FeedbackSource &feedback, int flags)
Definition: maglev-ir.h:5774
const compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor_
Definition: maglev-ir.h:5801
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5798
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:5802
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:5788
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void MarkTaggedInputsAsDecompressing()
Definition: maglev-ir.h:7560
void VerifyInputs(MaglevGraphLabeller *) const
Definition: maglev-ir.h:7559
Dead(uint64_t bitfield)
Definition: maglev-ir.h:7563
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7558
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Definition: maglev-ir.h:7557
void GenerateCode(MaglevAssembler *, const ProcessingState &)
DebugBreak(uint64_t bitfield)
Definition: maglev-ir.h:7543
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7549
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9752
DefineKeyedOwnGeneric(uint64_t bitfield, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9725
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9736
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9755
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9616
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9600
void GenerateCode(MaglevAssembler *, const ProcessingState &)
DefineNamedOwnGeneric(uint64_t bitfield, compiler::NameRef name, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9589
DeleteProperty(uint64_t bitfield, LanguageMode mode)
Definition: maglev-ir.h:5165
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7937
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5170
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5169
SourcePosition GetSourcePosition() const
Definition: maglev-ir.h:1798
const InlinedArgumentsDeoptFrame & as_inlined_arguments() const
Definition: maglev-ir.h:1664
const ConstructInvokeStubDeoptFrame & as_construct_stub() const
Definition: maglev-ir.h:1703
compiler::SharedFunctionInfoRef GetSharedFunctionInfo() const
Definition: maglev-ir.h:1813
DeoptFrame(InterpretedFrameData &&data, DeoptFrame *parent)
Definition: maglev-ir.h:1581
const DeoptFrame * parent() const
Definition: maglev-ir.h:1561
DeoptFrame(const FrameData &data, DeoptFrame *parent)
Definition: maglev-ir.h:1556
DeoptFrame(FrameData &&data, DeoptFrame *parent)
Definition: maglev-ir.h:1553
DeoptFrame(InlinedArgumentsFrameData &&data, DeoptFrame *parent)
Definition: maglev-ir.h:1583
const InterpretedDeoptFrame & as_interpreted() const
Definition: maglev-ir.h:1626
const MaglevCompilationUnit & GetCompilationUnit() const
Definition: maglev-ir.h:1770
compiler::BytecodeArrayRef GetBytecodeArray() const
Definition: maglev-ir.h:1818
DeoptFrame(ConstructInvokeStubFrameData &&data, DeoptFrame *parent)
Definition: maglev-ir.h:1585
const BuiltinContinuationDeoptFrame & as_builtin_continuation() const
Definition: maglev-ir.h:1747
BytecodeOffset GetBytecodeOffset() const
Definition: maglev-ir.h:1783
DeoptFrame(BuiltinContinuationFrameData &&data, DeoptFrame *parent)
Definition: maglev-ir.h:1587
InputLocation * input_locations() const
Definition: maglev-ir.h:1835
const DeoptFrame & top_frame() const
Definition: maglev-ir.h:1829
void set_translation_index(int index)
Definition: maglev-ir.h:1844
InputLocation * input_locations_
Definition: maglev-ir.h:1853
void InitializeInputLocations(Zone *zone, size_t count)
Definition: maglev-ir.cc:341
const compiler::FeedbackSource & feedback_to_update() const
Definition: maglev-ir.h:1830
DeoptInfo(Zone *zone, const DeoptFrame top_frame, compiler::FeedbackSource feedback_to_update)
Definition: maglev-ir.cc:384
const compiler::FeedbackSource feedback_to_update_
Definition: maglev-ir.h:1852
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Deopt(uint64_t bitfield, DeoptimizeReason reason)
Definition: maglev-ir.h:11400
EagerDeoptInfo(Zone *zone, const DeoptFrame top_frame, compiler::FeedbackSource feedback_to_update)
Definition: maglev-ir.h:1869
DeoptimizeReason reason() const
Definition: maglev-ir.h:1873
void set_reason(DeoptimizeReason reason)
Definition: maglev-ir.h:1874
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8357
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ExceptionHandlerInfo(BasicBlockRef *catch_block_ref, int depth)
Definition: maglev-ir.h:1991
ExceptionHandlerInfo(BasicBlock *catch_block_ref, int depth)
Definition: maglev-ir.h:1997
ExceptionHandlerInfo(Mode mode=kNoExceptionHandler)
Definition: maglev-ir.h:1988
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ExtendPropertiesBackingStore(uint64_t bitfield, int old_length)
Definition: maglev-ir.h:8365
const compiler::SharedFunctionInfoRef shared_function_info_
Definition: maglev-ir.h:6655
FastCreateClosure(uint64_t bitfield, compiler::SharedFunctionInfoRef shared_function_info, compiler::FeedbackCellRef feedback_cell)
Definition: maglev-ir.h:6628
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::SharedFunctionInfoRef shared_function_info() const
Definition: maglev-ir.h:6635
compiler::FeedbackCellRef feedback_cell() const
Definition: maglev-ir.h:6638
const compiler::FeedbackCellRef feedback_cell_
Definition: maglev-ir.h:6656
detail::YouNeedToDefineAnInputTypesArrayInYourDerivedClass kInputTypes
Definition: maglev-ir.h:3027
void VerifyInputs(MaglevGraphLabeller *graph_labeller) const
Definition: maglev-ir.h:2998
FixedInputNodeTMixin(uint64_t bitfield, Args &&... args)
Definition: maglev-ir.h:3030
detail::ArrayWrapper< kInputCount > InputTypes
Definition: maglev-ir.h:3026
constexpr uint16_t input_count() const
Definition: maglev-ir.h:2993
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4446
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4438
Float64Abs(uint64_t bitfield)
Definition: maglev-ir.h:4436
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4440
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3442
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3455
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3444
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3410
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3411
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3422
Float64Compare(uint64_t bitfield, Operation operation)
Definition: maglev-ir.h:3485
static constexpr int kRightIndex
Definition: maglev-ir.h:3492
void GenerateCode(MaglevAssembler *, const ProcessingState &)
constexpr Operation operation() const
Definition: maglev-ir.h:3496
static constexpr int kLeftIndex
Definition: maglev-ir.h:3491
NextBitField< Operation, 5 > OperationBitField
Definition: maglev-ir.h:3507
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8306
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3488
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3965
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:3969
Float64Constant(uint64_t bitfield, Float64 value)
Definition: maglev-ir.h:3959
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1227
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7909
Float64Constant(uint64_t bitfield, uint64_t bitpattern)
Definition: maglev-ir.h:3962
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4496
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4503
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4497
ExternalReference ieee_function_ref() const
Definition: maglev-ir.cc:826
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3587
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8337
Ieee754Function ieee_function() const
Definition: maglev-ir.h:3598
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Float64Ieee754Unary(uint64_t bitfield, Ieee754Function ieee_function)
Definition: maglev-ir.h:3581
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3584
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3542
Float64Negate(uint64_t bitfield)
Definition: maglev-ir.h:3538
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3548
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3540
Float64Round(uint64_t bitfield, Kind kind)
Definition: maglev-ir.h:4523
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8349
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4527
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4525
static Builtin continuation(Kind kind)
Definition: maglev-ir.h:4512
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8311
NextBitField< bool, 1 > FlipBitField
Definition: maglev-ir.h:3531
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Float64ToBoolean(uint64_t bitfield, bool flip)
Definition: maglev-ir.h:3514
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3517
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4162
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4164
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4173
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4125
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4136
Float64ToTagged(uint64_t bitfield, ConversionMode mode)
Definition: maglev-ir.h:4122
ConversionMode conversion_mode() const
Definition: maglev-ir.h:4140
NextBitField< ConversionMode, 1 > ConversionModeBitField
Definition: maglev-ir.h:4150
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4127
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4027
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4035
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4029
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:5323
ForInNext(uint64_t bitfield, compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:5314
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:5337
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5334
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5317
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5318
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5291
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:5294
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5304
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5289
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:5307
ForInPrepare(uint64_t bitfield, compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:5286
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7584
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::AllocatedOperand source_
Definition: maglev-ir.h:9774
compiler::AllocatedOperand target() const
Definition: maglev-ir.h:9767
compiler::AllocatedOperand target_
Definition: maglev-ir.h:9775
GapMove(uint64_t bitfield, compiler::AllocatedOperand source, compiler::AllocatedOperand target)
Definition: maglev-ir.h:9762
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::AllocatedOperand source() const
Definition: maglev-ir.h:9766
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5471
void GenerateCode(MaglevAssembler *, const ProcessingState &)
GeneratorRestoreRegister(uint64_t bitfield, int index)
Definition: maglev-ir.h:5467
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5470
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5480
static constexpr int kGeneratorIndex
Definition: maglev-ir.h:5195
static constexpr int kFixedInputCount
Definition: maglev-ir.h:5196
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5209
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5238
void GenerateCode(MaglevAssembler *, const ProcessingState &)
GeneratorStore(uint64_t bitfield, ValueNode *context, ValueNode *generator, int suspend_id, int bytecode_offset)
Definition: maglev-ir.h:5200
void set_parameters_and_registers(int i, ValueNode *node)
Definition: maglev-ir.h:5223
void VerifyInputs(MaglevGraphLabeller *graph_labeller) const
Definition: maglev-ir.cc:894
static constexpr int kContextIndex
Definition: maglev-ir.h:5194
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11167
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5365
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5352
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5351
IndirectHandle< FeedbackVector > feedback() const
Definition: maglev-ir.h:5360
GetIterator(uint64_t bitfield, int load_slot, int call_slot, compiler::FeedbackVectorRef feedback)
Definition: maglev-ir.h:5344
const IndirectHandle< FeedbackVector > feedback_
Definition: maglev-ir.h:5370
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9683
GetKeyedGeneric(uint64_t bitfield, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9658
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9680
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9668
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5381
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5386
compiler::SharedFunctionInfoRef shared_function_info_
Definition: maglev-ir.h:7675
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7672
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:7676
GetTemplateObject(uint64_t bitfield, compiler::SharedFunctionInfoRef shared_function_info, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:7649
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:7667
compiler::SharedFunctionInfoRef shared_function_info()
Definition: maglev-ir.h:7664
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10907
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::HeapObjectRef prototype_
Definition: maglev-ir.h:7705
void GenerateCode(MaglevAssembler *, const ProcessingState &)
HasInPrototypeChain(uint64_t bitfield, compiler::HeapObjectRef prototype)
Definition: maglev-ir.h:7684
compiler::HeapObjectRef prototype()
Definition: maglev-ir.h:7697
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4809
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4815
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4759
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4752
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4187
ConversionMode conversion_mode() const
Definition: maglev-ir.h:4204
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4185
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4196
void SetMode(ConversionMode mode)
Definition: maglev-ir.h:4198
NextBitField< ConversionMode, 1 > ConversionModeBitField
Definition: maglev-ir.h:4213
void GenerateCode(MaglevAssembler *, const ProcessingState &)
HoleyFloat64ToTagged(uint64_t bitfield, ConversionMode mode)
Definition: maglev-ir.h:4182
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3076
Identity(uint64_t bitfield)
Definition: maglev-ir.h:3062
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Definition: maglev-ir.h:3075
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3060
void VerifyInputs(MaglevGraphLabeller *) const
Definition: maglev-ir.h:3064
interpreter::Register source() const
Definition: maglev-ir.h:5492
const interpreter::Register source_
Definition: maglev-ir.h:5503
static uint32_t stack_slot(uint32_t register_idx)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7942
InitialValue(uint64_t bitfield, interpreter::Register source)
Definition: maglev-ir.cc:167
static constexpr OpProperties kProperties
Definition: maglev-ir.h:6278
EscapeAnalysisResult escape_analysis_result_
Definition: maglev-ir.h:6355
void VerifyInputs(MaglevGraphLabeller *graph_labeller) const
Definition: maglev-ir.cc:1143
void UpdateObject(VirtualObject *object)
Definition: maglev-ir.h:6338
void GenerateCode(MaglevAssembler *, const ProcessingState &)
InlinedAllocation(uint64_t bitfield, VirtualObject *object)
Definition: maglev-ir.h:6270
VirtualObject * object() const
Definition: maglev-ir.h:6290
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:6280
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7993
const MaglevCompilationUnit & unit() const
Definition: maglev-ir.h:1646
const InlinedArgumentsFrameData & data() const
Definition: maglev-ir.h:1656
InlinedArgumentsDeoptFrame(const MaglevCompilationUnit &unit, BytecodeOffset bytecode_position, ValueNode *closure, base::Vector< ValueNode * > arguments, DeoptFrame *parent)
Definition: maglev-ir.h:1637
base::Vector< ValueNode * > arguments() const
Definition: maglev-ir.h:1650
void set_node(ValueNode *node)
Definition: maglev-ir.h:1499
Input(ValueNode *node)
Definition: maglev-ir.h:1497
ValueNode * node() const
Definition: maglev-ir.h:1498
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4429
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4417
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4420
static constexpr int kRightIndex
Definition: maglev-ir.h:3209
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3204
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3205
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3164
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3175
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3162
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3234
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr int kValueIndex
Definition: maglev-ir.h:3236
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3232
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3241
static constexpr int kLeftIndex
Definition: maglev-ir.h:3302
constexpr Operation operation() const
Definition: maglev-ir.h:3307
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8318
Int32Compare(uint64_t bitfield, Operation operation)
Definition: maglev-ir.h:3296
NextBitField< Operation, 5 > OperationBitField
Definition: maglev-ir.h:3318
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3299
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr int kRightIndex
Definition: maglev-ir.h:3303
void GenerateCode(MaglevAssembler *, const ProcessingState &)
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:3888
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3884
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7894
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1215
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
Int32Constant(uint64_t bitfield, int32_t value)
Definition: maglev-ir.h:3881
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4464
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4456
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4458
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3279
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3278
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3289
NextBitField< bool, 1 > FlipBitField
Definition: maglev-ir.h:3341
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3328
constexpr bool flip() const
Definition: maglev-ir.h:3332
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8323
Int32ToBoolean(uint64_t bitfield, bool flip)
Definition: maglev-ir.h:3325
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4074
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Int32ToNumber(uint64_t bitfield)
Definition: maglev-ir.h:4061
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4067
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4063
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3991
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3993
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3999
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3249
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3252
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1223
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:3940
IntPtrConstant(uint64_t bitfield, intptr_t value)
Definition: maglev-ir.h:3933
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7904
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3936
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3351
NextBitField< bool, 1 > FlipBitField
Definition: maglev-ir.h:3364
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8330
IntPtrToBoolean(uint64_t bitfield, bool flip)
Definition: maglev-ir.h:3348
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4103
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4114
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4107
int ComputeReturnOffset(interpreter::Register result_location, int result_size) const
Definition: maglev-ir.cc:413
const MaglevCompilationUnit & unit() const
Definition: maglev-ir.h:1604
InterpretedDeoptFrame(const MaglevCompilationUnit &unit, const CompactInterpreterFrameState *frame_state, ValueNode *closure, BytecodeOffset bytecode_position, SourcePosition source_position, DeoptFrame *parent)
Definition: maglev-ir.h:1596
BytecodeOffset bytecode_position() const
Definition: maglev-ir.h:1610
const InterpretedFrameData & data() const
Definition: maglev-ir.h:1618
const CompactInterpreterFrameState * frame_state() const
Definition: maglev-ir.h:1605
void GenerateCode(MaglevAssembler *, const ProcessingState &)
JumpLoop(uint64_t bitfield, BasicBlock *target)
Definition: maglev-ir.h:11337
base::Vector< Input > used_nodes()
Definition: maglev-ir.h:11347
base::Vector< Input > used_node_locations_
Definition: maglev-ir.h:11353
void set_used_nodes(base::Vector< Input > locations)
Definition: maglev-ir.h:11348
JumpLoop(uint64_t bitfield, BasicBlockRef *ref)
Definition: maglev-ir.h:11340
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11345
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11314
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Jump(uint64_t bitfield, BasicBlockRef *target_refs)
Definition: maglev-ir.h:11309
interpreter::Register result_location_
Definition: maglev-ir.h:1969
interpreter::Register result_location() const
Definition: maglev-ir.h:1896
static bool InReturnValues(interpreter::Register reg, interpreter::Register result_location, int result_size)
Definition: maglev-ir.cc:403
static constexpr unsigned int kUninitializedCallReturnPc
Definition: maglev-ir.h:1967
bool IsResultRegister(interpreter::Register reg) const
Definition: maglev-ir.cc:388
static constexpr int kMaxCodeSize
Definition: maglev-ir.h:1966
LazyDeoptInfo(Zone *zone, const DeoptFrame top_frame, interpreter::Register result_location, int result_size, compiler::FeedbackSource feedback_to_update)
Definition: maglev-ir.h:1887
const InterpretedDeoptFrame & GetFrameForExceptionHandler(const ExceptionHandlerInfo *handler_info)
Definition: maglev-ir.cc:436
LoadDoubleDataViewElement(uint64_t bitfield, ExternalArrayType type)
Definition: maglev-ir.h:8636
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8660
void GenerateCode(MaglevAssembler *, const ProcessingState &)
LoadDoubleField(uint64_t bitfield, int offset)
Definition: maglev-ir.h:8207
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9441
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8511
void GenerateCode(MaglevAssembler *, const ProcessingState &)
LoadFloat64(uint64_t bitfield, int offset)
Definition: maglev-ir.h:8234
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::NameRef name_
Definition: maglev-ir.h:9262
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9263
LoadGlobal(uint64_t bitfield, compiler::NameRef name, const compiler::FeedbackSource &feedback, TypeofMode typeof_mode)
Definition: maglev-ir.h:9237
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9251
TypeofMode typeof_mode() const
Definition: maglev-ir.h:9252
compiler::NameRef name() const
Definition: maglev-ir.h:9250
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8560
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8534
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
LoadInt32(uint64_t bitfield, int offset)
Definition: maglev-ir.h:8261
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9371
LoadNamedFromSuperGeneric(uint64_t bitfield, compiler::NameRef name, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9360
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9387
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::NameRef name() const
Definition: maglev-ir.h:9337
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9352
const compiler::NameRef name_
Definition: maglev-ir.h:9351
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9338
LoadNamedGeneric(uint64_t bitfield, compiler::NameRef name, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9328
LoadSignedIntDataViewElement(uint64_t bitfield, ExternalArrayType type)
Definition: maglev-ir.h:8592
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8619
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8312
void GenerateCode(MaglevAssembler *, const ProcessingState &)
LoadTaggedFieldForContextSlotNoCells(uint64_t bitfield, const int offset)
Definition: maglev-ir.h:8165
void GenerateCode(MaglevAssembler *, const ProcessingState &)
LoadTaggedFieldForContextSlot(uint64_t bitfield, const int offset)
Definition: maglev-ir.h:8175
LoadTaggedFieldForProperty(uint64_t bitfield, const int offset, compiler::NameRef name)
Definition: maglev-ir.h:8149
LoadTaggedField(uint64_t bitfield, const int offset)
Definition: maglev-ir.h:8140
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7454
LoadTypedArrayLength(uint64_t bitfield, ElementsKind elements_kind)
Definition: maglev-ir.h:7442
void GenerateCode(MaglevAssembler *, const ProcessingState &)
LogicalNot(uint64_t bitfield)
Definition: maglev-ir.h:4885
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4894
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4888
compiler::SharedFunctionInfoRef shared_function_info() const
compiler::BytecodeArrayRef bytecode() const
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7834
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7813
MaybeGrowFastElements(uint64_t bitfield, ElementsKind elements_kind)
Definition: maglev-ir.h:8397
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8421
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7381
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void set_properties(OpProperties properties)
Definition: maglev-ir.h:2144
Address exception_handler_address() const
Definition: maglev-ir.h:2478
void set_temporaries_needed(uint8_t value)
Definition: maglev-ir.h:2381
static constexpr OpProperties kProperties
Definition: maglev-ir.h:2137
void set_owner(BasicBlock *block)
Definition: maglev-ir.h:2327
void RequireSpecificTemporary(Register reg)
Definition: maglev-ir.h:2393
void OverwriteWithIdentityTo(ValueNode *node)
constexpr uint64_t bitfield() const
Definition: maglev-ir.h:2337
void change_representation(ValueRepresentation new_repr)
Definition: maglev-ir.h:2277
InputCountField::Next< bool, 1 > ReservedField
Definition: maglev-ir.h:2098
constexpr bool Is() const
Definition: maglev-ir.h:2552
static constexpr size_t RegisterSnapshotSize(OpProperties properties)
Definition: maglev-ir.h:2443
NodeBase(const NodeBase &)=delete
const Input * last_input() const
Definition: maglev-ir.h:2358
void set_input(int index, ValueNode *node)
Definition: maglev-ir.h:2915
static constexpr int kMaxInputs
Definition: maglev-ir.h:2103
DoubleRegList & double_temporaries()
Definition: maglev-ir.h:2223
Address last_input_address() const
Definition: maglev-ir.h:2360
static constexpr Opcode opcode_of
Definition: maglev-ir.h:2107
static Derived * Allocate(Zone *zone, size_t input_count, Args &&... args)
Definition: maglev-ir.h:2403
constexpr const Input & input(int index) const
Definition: maglev-ir.h:2183
constexpr Input * input_base()
Definition: maglev-ir.h:2351
NodeBase & operator=(NodeBase &&)=delete
constexpr bool has_inputs() const
Definition: maglev-ir.h:2173
RegListBase< RegisterT > & temporaries()
Definition: maglev-ir.h:2219
OwnerOrTemporaries owner_or_temporaries_
Definition: maglev-ir.h:2542
void assign_temporaries(RegListBase< RegisterT > list)
Definition: maglev-ir.h:2226
static constexpr size_t LazyDeoptInfoSize(OpProperties properties)
Definition: maglev-ir.h:2455
constexpr const T * Cast() const
Definition: maglev-ir.h:2159
void reduce_input_count(int num=1)
Definition: maglev-ir.h:2369
static constexpr size_t EagerDeoptInfoSize(OpProperties properties)
Definition: maglev-ir.h:2448
void ForAllInputsInRegallocAssignmentOrder(Function &&f)
Definition: maglev-ir.h:11862
constexpr const Input * input_base() const
Definition: maglev-ir.h:2354
void CopyEagerDeoptInfoOf(NodeBase *other, Zone *zone)
Definition: maglev-ir.h:2287
constexpr NodeIdT id() const
Definition: maglev-ir.h:2199
void ClearUnstableNodeAspects(KnownNodeAspects &)
Definition: maglev-ir.cc:8492
NodeBase(uint64_t bitfield)
Definition: maglev-ir.h:2334
void SetEagerDeoptInfo(Zone *zone, DeoptFrame deopt_frame, compiler::FeedbackSource feedback_to_update=compiler::FeedbackSource())
Definition: maglev-ir.h:2293
void change_input(int index, ValueNode *node)
static constexpr size_t ExceptionHandlerInfoSize(OpProperties properties)
Definition: maglev-ir.h:2438
Address deopt_info_address() const
Definition: maglev-ir.h:2462
Address register_snapshot_address() const
Definition: maglev-ir.h:2471
static Derived * New(Zone *zone, std::initializer_list< ValueNode * > inputs, Args &&... args)
Definition: maglev-ir.h:2110
void ClearElementsProperties(KnownNodeAspects &)
Definition: maglev-ir.cc:8479
const RegisterSnapshot & register_snapshot() const
Definition: maglev-ir.h:2259
void CheckCanOverwriteWith(Opcode new_opcode, OpProperties new_properties)
void set_bitfield(uint64_t new_bitfield)
Definition: maglev-ir.h:2338
constexpr int input_count() const
Definition: maglev-ir.h:2174
constexpr Input & input(int index)
Definition: maglev-ir.h:2179
void set_opcode(Opcode new_opcode)
Definition: maglev-ir.h:2283
uint8_t num_temporaries_needed() const
Definition: maglev-ir.h:2210
constexpr const T * TryCast() const
Definition: maglev-ir.h:2169
NodeBase(NodeBase &&)=delete
void set_double_temporaries_needed(uint8_t value)
Definition: maglev-ir.h:2386
void RequireSpecificDoubleTemporary(DoubleRegister reg)
Definition: maglev-ir.h:2397
constexpr bool has_id() const
Definition: maglev-ir.h:2198
void set_register_snapshot(RegisterSnapshot snapshot)
Definition: maglev-ir.h:2269
void initialize_input_null(int index)
Definition: maglev-ir.h:2909
LazyDeoptInfo * lazy_deopt_info()
Definition: maglev-ir.h:2253
std::optional< int32_t > TryGetInt32ConstantInput(int index)
Definition: maglev-ir.cc:8552
constexpr Opcode opcode() const
Definition: maglev-ir.h:2140
void OverwriteWith(Opcode new_opcode, std::optional< OpProperties > maybe_new_properties=std::nullopt)
Definition: maglev-ir.h:2307
NodeBase & operator=(const NodeBase &)=delete
EagerDeoptInfo * eager_deopt_info()
Definition: maglev-ir.h:2246
BasicBlock * owner() const
Definition: maglev-ir.h:2329
ExceptionHandlerInfo * exception_handler_info()
Definition: maglev-ir.h:2264
constexpr OpProperties properties() const
Definition: maglev-ir.h:2141
static Derived * New(Zone *zone, size_t input_count, Args &&... args)
Definition: maglev-ir.h:2130
static Derived * New(Zone *zone, std::initializer_list< ValueNode * > inputs, Args &&... args)
Definition: maglev-ir.h:2951
NodeTMixin(uint64_t bitfield, Args &&... args)
Definition: maglev-ir.h:2962
constexpr const OpProperties & properties() const
Definition: maglev-ir.h:2946
static Derived * New(Zone *zone, size_t input_count, Args &&... args)
Definition: maglev-ir.h:2956
constexpr Opcode opcode() const
Definition: maglev-ir.h:2945
ValueLocation & result()
Definition: maglev-ir.h:2934
static constexpr bool needs_epoch_check(Opcode op)
Definition: maglev-ir.h:2599
static constexpr bool participate_in_cse(Opcode op)
Definition: maglev-ir.h:2591
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5452
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5448
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5459
static const uint32_t kPureMask
Definition: maglev-ir.h:1399
static constexpr OpProperties TaggedValue()
Definition: maglev-ir.h:1312
constexpr bool can_allocate() const
Definition: maglev-ir.h:1237
static constexpr OpProperties ConversionNode()
Definition: maglev-ir.h:1348
constexpr bool needs_register_snapshot() const
Definition: maglev-ir.h:1256
constexpr bool is_required_when_unused() const
Definition: maglev-ir.h:1262
constexpr bool can_read() const
Definition: maglev-ir.h:1235
static constexpr OpProperties CanCallUserCode()
Definition: maglev-ir.h:1351
constexpr OpProperties(uint32_t bitfield)
Definition: maglev-ir.h:1373
static constexpr OpProperties CanThrow()
Definition: maglev-ir.h:1296
static constexpr OpProperties IntPtr()
Definition: maglev-ir.h:1336
constexpr bool can_throw() const
Definition: maglev-ir.h:1230
static constexpr OpProperties CanRead()
Definition: maglev-ir.h:1300
static constexpr OpProperties DeferredCall()
Definition: maglev-ir.h:1366
static constexpr OpProperties CanAllocate()
Definition: maglev-ir.h:1306
constexpr bool is_deopt_checkpoint() const
Definition: maglev-ir.h:1223
static constexpr OpProperties Int32()
Definition: maglev-ir.h:1320
constexpr bool can_eager_deopt() const
Definition: maglev-ir.h:1215
static constexpr OpProperties AnySideEffects()
Definition: maglev-ir.h:1363
constexpr OpProperties operator|(const OpProperties &that)
Definition: maglev-ir.h:1276
OpProperties WithNewValueRepresentation(ValueRepresentation new_repr) const
Definition: maglev-ir.h:1376
constexpr bool can_lazy_deopt() const
Definition: maglev-ir.h:1219
static constexpr OpProperties Call()
Definition: maglev-ir.h:1281
static constexpr OpProperties JSCall()
Definition: maglev-ir.h:1362
static constexpr OpProperties Uint32()
Definition: maglev-ir.h:1324
OpProperties WithoutDeopt() const
Definition: maglev-ir.h:1380
static constexpr OpProperties LazyDeopt()
Definition: maglev-ir.h:1288
static constexpr OpProperties Pure()
Definition: maglev-ir.h:1280
static constexpr OpProperties CanWrite()
Definition: maglev-ir.h:1303
constexpr bool is_any_call() const
Definition: maglev-ir.h:1214
constexpr ValueRepresentation value_representation() const
Definition: maglev-ir.h:1247
constexpr bool is_conversion() const
Definition: maglev-ir.h:1253
constexpr bool is_call() const
Definition: maglev-ir.h:1209
static constexpr OpProperties DeoptCheckpoint()
Definition: maglev-ir.h:1292
static constexpr OpProperties NeedsRegisterSnapshot()
Definition: maglev-ir.h:1409
static constexpr OpProperties Float64()
Definition: maglev-ir.h:1328
static constexpr OpProperties ForValueRepresentation(ValueRepresentation repr)
Definition: maglev-ir.h:1344
constexpr bool is_deferred_call() const
Definition: maglev-ir.h:1418
constexpr bool is_pure() const
Definition: maglev-ir.h:1259
constexpr bool is_tagged() const
Definition: maglev-ir.h:1250
static constexpr OpProperties ExternalReference()
Definition: maglev-ir.h:1316
constexpr bool not_idempotent() const
Definition: maglev-ir.h:1244
static constexpr OpProperties GenericRuntimeOrBuiltinCall()
Definition: maglev-ir.h:1359
static const uint32_t kPureValue
Definition: maglev-ir.h:1401
constexpr bool can_write() const
Definition: maglev-ir.h:1236
static constexpr OpProperties EagerDeopt()
Definition: maglev-ir.h:1284
static constexpr OpProperties NotIdempotent()
Definition: maglev-ir.h:1309
static constexpr OpProperties HoleyFloat64()
Definition: maglev-ir.h:1332
constexpr bool can_participate_in_cse() const
Definition: maglev-ir.h:1272
static constexpr OpProperties TrustedPointer()
Definition: maglev-ir.h:1340
constexpr bool can_deopt() const
Definition: maglev-ir.h:1227
UseRepresentationSet get_same_loop_uses_repr_hints()
Definition: maglev-ir.h:9898
NodeType type() const
Definition: maglev-ir.h:9927
const interpreter::Register owner_
Definition: maglev-ir.h:9965
Requires31BitValueFlag::Next< bool, 1 > LoopPhiAfterLoopFlag
Definition: maglev-ir.h:9963
void merge_type(NodeType type)
Definition: maglev-ir.h:9919
bool uses_require_31_bit_value() const
Definition: maglev-ir.h:9948
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const MergePointInterpreterFrameState * merge_state() const
Definition: maglev-ir.h:9860
NextBitField< bool, 1 > HasKeyFlag
Definition: maglev-ir.h:9961
bool is_backedge_offset(int i) const
Definition: maglev-ir.h:9871
Phi(uint64_t bitfield, MergePointInterpreterFrameState *merge_state, interpreter::Register owner)
Definition: maglev-ir.h:9847
void set_post_loop_type(NodeType type)
Definition: maglev-ir.h:9907
MergePointInterpreterFrameState *const merge_state_
Definition: maglev-ir.h:9971
NodeType post_loop_type() const
Definition: maglev-ir.h:9902
void merge_post_loop_type(NodeType type)
Definition: maglev-ir.h:9903
bool is_exception_phi() const
Definition: maglev-ir.h:9868
void set_type(NodeType type)
Definition: maglev-ir.h:9923
UseRepresentationSet get_uses_repr_hints()
Definition: maglev-ir.h:9897
void set_uses_require_31_bit_value()
Definition: maglev-ir.h:9951
interpreter::Register owner() const
Definition: maglev-ir.h:9859
void RecordUseReprHint(UseRepresentation repr)
Definition: maglev-ir.h:9891
HasKeyFlag::Next< bool, 1 > Requires31BitValueFlag
Definition: maglev-ir.h:9962
const compiler::ObjectRef constant_
Definition: maglev-ir.h:8096
static PolymorphicAccessInfo Constant(const ZoneVector< compiler::MapRef > &maps, compiler::ObjectRef constant)
Definition: maglev-ir.h:7943
static PolymorphicAccessInfo ConstantDouble(const ZoneVector< compiler::MapRef > &maps, Float64 constant)
Definition: maglev-ir.h:7948
compiler::OptionalJSObjectRef holder() const
Definition: maglev-ir.h:7987
static PolymorphicAccessInfo ModuleExport(const ZoneVector< compiler::MapRef > &maps, compiler::CellRef cell)
Definition: maglev-ir.h:7958
Representation field_representation() const
Definition: maglev-ir.h:7997
const compiler::OptionalJSObjectRef holder_
Definition: maglev-ir.h:8099
PolymorphicAccessInfo(Kind kind, const ZoneVector< compiler::MapRef > &maps, Representation representation, compiler::ObjectRef constant)
Definition: maglev-ir.h:8061
static PolymorphicAccessInfo StringLength(const ZoneVector< compiler::MapRef > &maps)
Definition: maglev-ir.h:7963
PolymorphicAccessInfo(Kind kind, const ZoneVector< compiler::MapRef > &maps, Representation representation)
Definition: maglev-ir.h:8054
DirectHandle< Cell > cell() const
Definition: maglev-ir.h:7982
struct v8::internal::maglev::PolymorphicAccessInfo::@103::@105 data_load_
static PolymorphicAccessInfo NotFound(const ZoneVector< compiler::MapRef > &maps)
Definition: maglev-ir.h:7939
DirectHandle< Object > constant() const
Definition: maglev-ir.h:7972
const ZoneVector< compiler::MapRef > maps_
Definition: maglev-ir.h:8093
PolymorphicAccessInfo(Kind kind, const ZoneVector< compiler::MapRef > &maps, Float64 constant)
Definition: maglev-ir.h:8071
const ZoneVector< compiler::MapRef > & maps() const
Definition: maglev-ir.h:7970
bool operator==(const PolymorphicAccessInfo &other) const
Definition: maglev-ir.h:7999
PolymorphicAccessInfo(Kind kind, const ZoneVector< compiler::MapRef > &maps, Representation representation, compiler::OptionalJSObjectRef holder, FieldIndex field_index)
Definition: maglev-ir.h:8080
static PolymorphicAccessInfo DataLoad(const ZoneVector< compiler::MapRef > &maps, Representation representation, compiler::OptionalJSObjectRef holder, FieldIndex field_index)
Definition: maglev-ir.h:7952
ReduceInterruptBudgetForLoop(uint64_t bitfield, int amount)
Definition: maglev-ir.h:10916
ReduceInterruptBudgetForReturn(uint64_t bitfield, int amount)
Definition: maglev-ir.h:10946
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5515
void GenerateCode(MaglevAssembler *, const ProcessingState &)
RegisterInput(uint64_t bitfield, Register input)
Definition: maglev-ir.h:5510
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7957
RestLength(uint64_t bitfield, int formal_parameter_count)
Definition: maglev-ir.h:6509
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:6514
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11393
Return(uint64_t bitfield)
Definition: maglev-ir.h:11382
RootConstant(uint64_t bitfield, RootIndex index)
Definition: maglev-ir.h:5618
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7962
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.cc:353
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Handle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1240
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9484
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11188
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9717
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9714
SetKeyedGeneric(uint64_t bitfield, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9690
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9700
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9421
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::NameRef name_
Definition: maglev-ir.h:9420
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9405
SetNamedGeneric(uint64_t bitfield, compiler::NameRef name, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9394
compiler::NameRef name() const
Definition: maglev-ir.h:9404
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4912
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4903
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4906
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7861
Tagged< Smi > value() const
Definition: maglev-ir.h:5536
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7884
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:5538
void GenerateCode(MaglevAssembler *, const ProcessingState &)
SmiConstant(uint64_t bitfield, int32_t value)
Definition: maglev-ir.h:5531
const Tagged< Smi > value_
Definition: maglev-ir.h:5550
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1207
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4483
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4477
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4474
void GenerateCode(MaglevAssembler *, const ProcessingState &)
StoreContextSlotWithWriteBarrier(uint64_t bitfield, int index)
Definition: maglev-ir.h:9151
void GenerateCode(MaglevAssembler *, const ProcessingState &)
StoreDoubleDataViewElement(uint64_t bitfield, ExternalArrayType type)
Definition: maglev-ir.h:8895
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8920
void GenerateCode(MaglevAssembler *, const ProcessingState &)
StoreDoubleField(uint64_t bitfield, int offset)
Definition: maglev-ir.h:8927
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8489
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8453
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8584
void GenerateCode(MaglevAssembler *, const ProcessingState &)
StoreFloat64(uint64_t bitfield, int offset)
Definition: maglev-ir.h:8979
StoreGlobal(uint64_t bitfield, compiler::NameRef name, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9271
const compiler::NameRef name_
Definition: maglev-ir.h:9292
void GenerateCode(MaglevAssembler *, const ProcessingState &)
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9281
compiler::NameRef name() const
Definition: maglev-ir.h:9280
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9293
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:9651
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9648
StoreInArrayLiteralGeneric(uint64_t bitfield, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:9624
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:9634
StoreInt32(uint64_t bitfield, int offset)
Definition: maglev-ir.h:8953
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const compiler::MapRef map_
Definition: maglev-ir.h:9098
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< Kind, 3 > KindField
Definition: maglev-ir.h:9097
StoreMap(uint64_t bitfield, compiler::MapRef map, Kind kind)
Definition: maglev-ir.h:9075
compiler::MapRef map() const
Definition: maglev-ir.h:9086
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:8882
StoreSignedIntDataViewElement(uint64_t bitfield, ExternalArrayType type)
Definition: maglev-ir.h:8854
void GenerateCode(MaglevAssembler *, const ProcessingState &)
StoreTaggedFieldNoWriteBarrier(uint64_t bitfield, int offset, StoreTaggedMode store_mode)
Definition: maglev-ir.h:9016
NextBitField< bool, 1 > InitializingOrTransitioningField
Definition: maglev-ir.h:9061
void GenerateCode(MaglevAssembler *, const ProcessingState &)
StoreTaggedFieldWithWriteBarrier(uint64_t bitfield, int offset, StoreTaggedMode store_mode)
Definition: maglev-ir.h:9107
void GenerateCode(MaglevAssembler *, const ProcessingState &)
StoreTrustedPointerFieldWithWriteBarrier(uint64_t bitfield, int offset, IndirectPointerTag tag, StoreTaggedMode store_mode)
Definition: maglev-ir.h:9189
StringAt(uint64_t bitfield)
Definition: maglev-ir.h:9448
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9464
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9525
StringConcat(uint64_t bitfield)
Definition: maglev-ir.h:9511
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4977
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4973
StringEqualInputs inputs() const
Definition: maglev-ir.h:4988
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4986
StringEqual(uint64_t bitfield, StringEqualInputs inputs)
Definition: maglev-ir.h:4971
StringLength(uint64_t bitfield)
Definition: maglev-ir.h:9491
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9504
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void set_fallthrough(BasicBlock *fallthrough)
Definition: maglev-ir.h:11447
Switch(uint64_t bitfield, int value_base, BasicBlockRef *targets, int size, BasicBlockRef *fallthrough)
Definition: maglev-ir.h:11426
Switch(uint64_t bitfield, int value_base, BasicBlockRef *targets, int size)
Definition: maglev-ir.h:11418
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11456
BasicBlock * fallthrough() const
Definition: maglev-ir.h:11442
std::optional< BasicBlockRef > fallthrough_
Definition: maglev-ir.h:11462
BasicBlockRef * targets() const
Definition: maglev-ir.h:11438
TaggedEqual(uint64_t bitfield)
Definition: maglev-ir.h:4999
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5015
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5001
void GenerateCode(MaglevAssembler *, const ProcessingState &)
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:5567
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1211
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7889
TaggedIndexConstant(uint64_t bitfield, int value)
Definition: maglev-ir.h:5560
Tagged< TaggedIndex > value() const
Definition: maglev-ir.h:5565
const Tagged< TaggedIndex > value_
Definition: maglev-ir.h:5577
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5038
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5024
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5063
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5050
const compiler::FeedbackSource & feedback() const
Definition: maglev-ir.h:5058
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:5066
TestInstanceOf(uint64_t bitfield, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:5045
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5051
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5101
interpreter::TestTypeOfFlags::LiteralFlag literal_
Definition: maglev-ir.h:5114
TestTypeOf(uint64_t bitfield, interpreter::TestTypeOfFlags::LiteralFlag literal)
Definition: maglev-ir.h:5096
interpreter::TestTypeOfFlags::LiteralFlag literal() const
Definition: maglev-ir.h:5111
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8428
void GenerateCode(MaglevAssembler *, const ProcessingState &)
TestUndetectable(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:5073
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5084
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5077
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:5089
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11056
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11077
ThrowReferenceErrorIfHole(uint64_t bitfield, const compiler::NameRef name)
Definition: maglev-ir.h:10975
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:10991
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11037
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11016
ToBooleanLogicalNot(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:4944
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4955
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4948
void GenerateCode(MaglevAssembler *, const ProcessingState &)
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:4960
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:4936
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4931
CheckType check_type() const
Definition: maglev-ir.h:4927
ToBoolean(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:4920
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4924
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ToName(uint64_t bitfield)
Definition: maglev-ir.h:5121
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5124
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5134
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5125
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5144
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5155
ToNumberOrNumeric(uint64_t bitfield, Object::Conversion mode)
Definition: maglev-ir.h:5141
Object::Conversion mode() const
Definition: maglev-ir.h:5150
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5147
const Object::Conversion mode_
Definition: maglev-ir.h:5158
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5397
CheckType check_type() const
Definition: maglev-ir.h:5403
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5408
NextBitField< CheckType, 1 > CheckTypeBitField
Definition: maglev-ir.h:5411
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5398
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ToObject(uint64_t bitfield, CheckType check_type)
Definition: maglev-ir.h:5393
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5424
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5436
NextBitField< ConversionMode, 1 > ConversionModeBitField
Definition: maglev-ir.h:5439
ConversionMode mode() const
Definition: maglev-ir.h:5429
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5423
ToString(uint64_t bitfield, ConversionMode mode)
Definition: maglev-ir.h:5419
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:7921
TransitionAndStoreArrayElement(uint64_t bitfield, const compiler::MapRef &fast_map, const compiler::MapRef &double_map)
Definition: maglev-ir.h:7896
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ZoneVector< compiler::MapRef > transition_sources_
Definition: maglev-ir.h:11153
const compiler::MapRef transition_target() const
Definition: maglev-ir.h:11148
TransitionElementsKindOrCheckMap(uint64_t bitfield, const ZoneVector< compiler::MapRef > &transition_sources, compiler::MapRef transition_target)
Definition: maglev-ir.h:11123
const ZoneVector< compiler::MapRef > & transition_sources() const
Definition: maglev-ir.h:11145
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const ZoneVector< compiler::MapRef > & transition_sources() const
Definition: maglev-ir.h:11106
const compiler::MapRef transition_target() const
Definition: maglev-ir.h:11109
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:11104
TransitionElementsKind(uint64_t bitfield, const ZoneVector< compiler::MapRef > &transition_sources, compiler::MapRef transition_target)
Definition: maglev-ir.h:11085
void GenerateCode(MaglevAssembler *, const ProcessingState &)
ZoneVector< compiler::MapRef > transition_sources_
Definition: maglev-ir.h:11114
void GenerateCode(MaglevAssembler *, const ProcessingState &)
TaggedToFloat64ConversionType conversion_type() const
Definition: maglev-ir.h:4838
NextBitField< TaggedToFloat64ConversionType, 2 > TaggedToFloat64ConversionTypeOffset
Definition: maglev-ir.h:4846
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8165
TruncateNumberOrOddballToInt32(uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
Definition: maglev-ir.h:4823
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4830
IndirectPointerTag tag() const
Definition: maglev-ir.h:5655
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7932
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:5648
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5646
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
TrustedConstant(uint64_t bitfield, compiler::HeapObjectRef object, IndirectPointerTag tag)
Definition: maglev-ir.h:5642
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1236
void GenerateCode(MaglevAssembler *, const ProcessingState &)
const IndirectPointerTag tag_
Definition: maglev-ir.h:5662
const compiler::HeapObjectRef object_
Definition: maglev-ir.h:5661
compiler::HeapObjectRef object() const
Definition: maglev-ir.h:5654
TryOnStackReplacement(uint64_t bitfield, int32_t loop_depth, FeedbackSlot feedback_slot, BytecodeOffset osr_offset, MaglevCompilationUnit *unit)
Definition: maglev-ir.h:5249
static constexpr OpProperties kProperties
Definition: maglev-ir.h:5259
MaglevCompilationUnit *const unit_
Definition: maglev-ir.h:5279
const MaglevCompilationUnit * unit() const
Definition: maglev-ir.h:5267
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:5263
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:5272
void DoLoadToRegister(MaglevAssembler *, OutputRegister)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:7899
Uint32Constant(uint64_t bitfield, uint32_t value)
Definition: maglev-ir.h:3907
bool ToBoolean(LocalIsolate *local_isolate) const
Definition: maglev-ir.h:3914
DirectHandle< Object > DoReify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1219
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3910
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4087
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4094
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4083
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4017
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4011
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4009
UnaryWithFeedbackNode(uint64_t bitfield, const compiler::FeedbackSource &feedback)
Definition: maglev-ir.h:3094
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3100
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3087
compiler::FeedbackSource feedback() const
Definition: maglev-ir.h:3091
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3085
const compiler::FeedbackSource feedback_
Definition: maglev-ir.h:3102
UncheckedNumberOrOddballToFloat64(uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
Definition: maglev-ir.h:4695
NextBitField< TaggedToFloat64ConversionType, 2 > TaggedToFloat64ConversionTypeOffset
Definition: maglev-ir.h:4719
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8155
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4703
void GenerateCode(MaglevAssembler *, const ProcessingState &)
TaggedToFloat64ConversionType conversion_type() const
Definition: maglev-ir.h:4711
UnconditionalControlNodeT(uint64_t bitfield, BasicBlockRef *target_refs)
Definition: maglev-ir.h:11244
UnconditionalControlNodeT(uint64_t bitfield, BasicBlock *target)
Definition: maglev-ir.h:11248
UnconditionalControlNode(uint64_t bitfield, BasicBlock *target)
Definition: maglev-ir.h:11230
UnconditionalControlNode(uint64_t bitfield, BasicBlockRef *target_refs)
Definition: maglev-ir.h:11227
static constexpr OpProperties kProperties
Definition: maglev-ir.h:4283
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:4292
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:4286
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3761
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3775
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3763
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3811
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3823
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3809
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3787
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3785
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3799
static constexpr OpProperties kProperties
Definition: maglev-ir.h:3857
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:3872
void GenerateCode(MaglevAssembler *, const ProcessingState &)
static constexpr Base::InputTypes kInputTypes
Definition: maglev-ir.h:3860
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9581
void GenerateCode(MaglevAssembler *, const ProcessingState &)
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.h:9321
compiler::InstructionOperand operand_
Definition: maglev-ir.h:1482
Register AssignedGeneralRegister() const
Definition: maglev-ir.h:1464
const compiler::InstructionOperand & operand() const
Definition: maglev-ir.h:1478
void SetUnallocated(Args &&... args)
Definition: maglev-ir.h:1436
void InjectLocation(compiler::InstructionOperand location)
Definition: maglev-ir.h:1448
void SetConstant(Args &&... args)
Definition: maglev-ir.h:1459
const compiler::InstructionOperand & operand()
Definition: maglev-ir.h:1479
void SetAllocated(Args &&... args)
Definition: maglev-ir.h:1442
DoubleRegister AssignedDoubleRegister() const
Definition: maglev-ir.h:1469
compiler::InstructionOperand hint_
Definition: maglev-ir.h:2901
const ValueLocation & result() const
Definition: maglev-ir.h:2617
bool unused_inputs_were_visited() const
Definition: maglev-ir.h:2625
void record_next_use(NodeIdT id, InputLocation *input_location)
Definition: maglev-ir.h:2702
compiler::InstructionOperand loadable_slot() const
Definition: maglev-ir.h:2696
constexpr ValueRepresentation value_representation() const
Definition: maglev-ir.h:2763
LiveRange live_range() const
Definition: maglev-ir.h:2719
void AddRegister(DoubleRegister reg)
Definition: maglev-ir.h:2804
NodeIdT current_next_use() const
Definition: maglev-ir.h:2720
compiler::AllocatedOperand spill_slot() const
Definition: maglev-ir.h:2691
void LoadToRegister(MaglevAssembler *, DoubleRegister)
constexpr bool is_tagged() const
Definition: maglev-ir.h:2732
ValueNode(uint64_t bitfield)
Definition: maglev-ir.h:2864
bool StaticTypeIs(compiler::JSHeapBroker *broker, NodeType type)
Definition: maglev-ir.h:2788
void advance_next_use(NodeIdT use)
Definition: maglev-ir.h:2724
void AddRegister(Register reg)
Definition: maglev-ir.h:2800
void Spill(compiler::AllocatedOperand operand)
Definition: maglev-ir.h:2677
DirectHandle< Object > Reify(LocalIsolate *isolate) const
Definition: maglev-ir.cc:1195
compiler::OptionalHeapObjectRef TryGetConstant(compiler::JSHeapBroker *broker)
Definition: maglev-ir.cc:503
void LoadToRegister(MaglevAssembler *, Register)
RegListBase< T > result_registers()
Definition: maglev-ir.h:2843
compiler::InstructionOperand spill_
Definition: maglev-ir.h:2899
RegListBase< T > ClearRegisters()
constexpr bool decompresses_tagged_result() const
Definition: maglev-ir.h:2760
void RemoveRegister(Register reg)
Definition: maglev-ir.h:2809
void DoLoadToRegister(MaglevAssembler *, Register)
compiler::InstructionOperand allocation() const
Definition: maglev-ir.h:2853
void SetHint(compiler::InstructionOperand hint)
Definition: maglev-ir.cc:467
NodeType GetStaticType(compiler::JSHeapBroker *broker)
Definition: maglev-ir.cc:515
constexpr bool use_double_register() const
Definition: maglev-ir.h:2728
constexpr MachineRepresentation GetMachineRepresentation() const
Definition: maglev-ir.h:2767
bool is_in_register(DoubleRegister reg) const
Definition: maglev-ir.h:2837
void DoLoadToRegister(MaglevAssembler *, DoubleRegister)
const compiler::InstructionOperand & hint() const
Definition: maglev-ir.h:2652
DoubleRegList double_registers_with_result_
Definition: maglev-ir.h:2892
bool is_in_register(Register reg) const
Definition: maglev-ir.h:2833
void RemoveRegister(DoubleRegister reg)
Definition: maglev-ir.h:2813
bool operator==(const Iterator &other) const
Definition: maglev-ir.h:6171
bool operator!=(const Iterator &other) const
Definition: maglev-ir.h:6174
void Add(VirtualObject *object)
Definition: maglev-ir.h:6188
void Print(std::ostream &os, const char *prefix, MaglevGraphLabeller *labeller) const
Definition: maglev-ir.cc:330
VirtualObject * FindAllocatedWith(const InlinedAllocation *allocation) const
Definition: maglev-ir.h:6197
static VirtualObject * WalkUntilCommon(const VirtualObjectList &list1, const VirtualObjectList &list2, Function &&f)
Definition: maglev-ir.h:6213
bool operator==(const VirtualObjectList &other) const
Definition: maglev-ir.h:6184
void ForEachNestedRuntimeInput(VirtualObjectList virtual_objects, Function &&f)
Definition: maglev-ir.h:6371
constexpr bool has_static_map() const
Definition: maglev-ir.h:5890
void set(uint32_t offset, ValueNode *value)
Definition: maglev-ir.h:5944
ValueNode * string_length() const
Definition: maglev-ir.h:5956
void ForEachInput(Function &&callback)
Definition: maglev-ir.h:6004
compiler::FixedDoubleArrayRef double_elements() const
Definition: maglev-ir.h:5931
VirtualObject(uint64_t bitfield, compiler::MapRef map, int id, uint32_t length, compiler::FixedDoubleArrayRef elements)
Definition: maglev-ir.h:5875
void GenerateCode(MaglevAssembler *, const ProcessingState &)
Definition: maglev-ir.h:5887
void ClearSlots(int last_init_slot, ValueNode *clear_value)
Definition: maglev-ir.h:5966
VirtualObject(uint64_t bitfield, compiler::MapRef map, int id, Float64 number)
Definition: maglev-ir.h:5865
void set_allocation(InlinedAllocation *allocation)
Definition: maglev-ir.h:5975
void ForEachInput(Function &&callback) const
Definition: maglev-ir.h:6024
ValueNode * get(uint32_t offset) const
Definition: maglev-ir.h:5936
std::optional< VirtualObject * > Merge(const VirtualObject *other, uint32_t new_object_id, Zone *zone, Function MergeValue) const
Definition: maglev-ir.h:6053
uint32_t double_elements_length() const
Definition: maglev-ir.h:5926
const VirtualConsString & cons_string() const
Definition: maglev-ir.h:5961
VirtualObject(uint64_t bitfield, compiler::MapRef map, int id, uint32_t slot_count, ValueNode **slots)
Definition: maglev-ir.h:5855
compiler::OptionalMapRef map_
Definition: maglev-ir.h:6141
ValueNode * get_by_index(uint32_t i) const
Definition: maglev-ir.h:6119
InlinedAllocation * allocation() const
Definition: maglev-ir.h:5974
compiler::MapRef map() const
Definition: maglev-ir.h:5901
void PrintParams(std::ostream &, MaglevGraphLabeller *) const
Definition: maglev-ir.cc:8002
VirtualObject(uint64_t bitfield, int id, const VirtualConsString &cons_string)
Definition: maglev-ir.h:5849
void set_by_index(uint32_t i, ValueNode *value)
Definition: maglev-ir.h:6124
bool compatible_for_merge(const VirtualObject *other) const
Definition: maglev-ir.h:5979
friend std::ostream & operator<<(std::ostream &out, Type type)
Definition: maglev-ir.h:5821
InlinedAllocation * allocation_
Definition: maglev-ir.h:6153
VirtualObject * Clone(uint32_t new_object_id, Zone *zone, bool empty_clone=false) const
Definition: maglev-ir.h:6079
constexpr ArrayWrapper(Args &&... args)
Definition: maglev-ir.h:2976
other heap size generate builtins concurrently on separate threads in mksnapshot track concurrent recompilation artificial compilation delay in ms max number of threads that concurrent Turbofan can create additional concurrent optimization jobs but throw away result whether maglev resets the interrupt budget whether maglev resets the OSR interrupt budget create additional concurrent optimization jobs maximum levels for nesting child serializers trace the heap broker(reports on missing data only)") DEFINE_INT(deopt_every_n_times
other heap size generate builtins concurrently on separate threads in mksnapshot track concurrent recompilation artificial compilation delay in ms max number of threads that concurrent Turbofan can use(0 for unbounded)") DEFINE_BOOL( stress_concurrent_inlining
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enables Turboshaft s StaticAssert and CheckTurboshaftTypeOf operations Wasm code into JS functions via the JS to Wasm wrappers are still inlined in TurboFan For controlling whether to at see turbo inline js wasm calls enable Turboshaft s loop unrolling enable an additional Turboshaft phase that performs optimizations based on type information enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps trace Turboshaft s if else to switch reducer invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the preconfigured old space Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enables Turboshaft s StaticAssert and CheckTurboshaftTypeOf operations Wasm code into JS functions via the JS to Wasm wrappers are still inlined in TurboFan For controlling whether to at see turbo inline js wasm calls enable Turboshaft s loop unrolling enable an additional Turboshaft phase that performs optimizations based on type information enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps trace Turboshaft s if else to switch reducer invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the preconfigured old space size(in Mbytes)") DEFINE_INT(random_gc_interval
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation nullptr
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enables Turboshaft s StaticAssert and CheckTurboshaftTypeOf operations Wasm code into JS functions via the JS to Wasm wrappers are still inlined in TurboFan For controlling whether to at see turbo inline js wasm calls enable Turboshaft s loop unrolling enable an additional Turboshaft phase that performs optimizations based on type information enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps trace Turboshaft s if else to switch reducer invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the preconfigured old space Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often Release pooled large pages after X seconds prints number of allocations and enables analysis mode for gc fuzz e g stress stress scavenge force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible discard the memory pool before invoking the GC on memory pressure or last resort GCs Delay before memory reducer start virtual randomize memory reservations by ignoring any hints passed when allocating pages use incremental marking for CppHeap cppheap_concurrent_marking c value for membalancer A special constant to balance between memory and space tradeoff The smaller the more memory it uses enable use of SSE4 instructions if available enable use of SAHF instruction if enable use of AVX VNNI instructions if available enable use of POPCNT instruction if available force all emitted branches to be in long mode(MIPS/PPC only)") DEFINE_BOOL(partial_constant_pool
other heap size flags(e.g. initial_heap_size) take precedence") DEFINE_SIZE_T( max_shared_heap_size
#define DEF_OPCODE_OF(Name)
Definition: maglev-ir.h:2046
#define DEF_FORWARD_DECLARATION(type,...)
Definition: maglev-ir.h:1091
#define CONDITIONAL_CONTROL_NODE_LIST(V)
Definition: maglev-ir.h:426
#define DEOPTIMIZE_REASON_FIELD
Definition: maglev-ir.h:2070
#define DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Name)
Definition: maglev-ir.h:3261
#define NODE_BASE_LIST(V)
Definition: maglev-ir.h:445
#define NODE_TYPE_LIST(V)
Definition: maglev-ir.h:701
#define STORE_TYPED_ARRAY(name, properties, type,...)
Definition: maglev-ir.h:8761
#define DEF_BINARY_WITH_FEEDBACK_NODE(Name)
Definition: maglev-ir.h:3148
#define LEAF_NODE_TYPE_LIST(V)
Definition: maglev-ir.h:637
#define LOAD_TYPED_ARRAY(name, properties,...)
Definition: maglev-ir.h:8665
#define ADD_STATIC_ASSERT(Name, Value)
Definition: maglev-ir.h:836
#define GAP_MOVE_NODE_LIST(V)
Definition: maglev-ir.h:332
#define NODE_LIST(V)
Definition: maglev-ir.h:404
#define DEF_UNARY_WITH_FEEDBACK_NODE(Name)
Definition: maglev-ir.h:3146
#define STORE_CONSTANT_TYPED_ARRAY(name, properties, type,...)
Definition: maglev-ir.h:8802
#define BRANCH_CONTROL_NODE_LIST(V)
Definition: maglev-ir.h:408
#define PLUS_ONE(type)
Definition: maglev-ir.h:453
#define VALUE_NODE_LIST(V)
Definition: maglev-ir.h:169
#define CONTROL_NODE_LIST(V)
Definition: maglev-ir.h:440
#define UNCONDITIONAL_CONTROL_NODE_LIST(V)
Definition: maglev-ir.h:430
#define DEF_FLOAT64_BINARY_NODE_WITH_CALL(Name)
Definition: maglev-ir.h:3460
#define IEEE_754_UNARY_LIST(V)
Definition: maglev-ir.h:3551
#define DEF_OPCODES(type)
Definition: maglev-ir.h:450
#define DEFINE_NODE_TYPE_CHECK(Type, _)
Definition: maglev-ir.h:995
#define DEF_FLOAT64_BINARY_NODE(Name)
Definition: maglev-ir.h:3458
#define DEF_INT32_BINARY_WITH_OVERFLOW_NODE(Name)
Definition: maglev-ir.h:3189
#define COUNT(...)
Definition: maglev-ir.h:674
#define TERMINAL_CONTROL_NODE_LIST(V)
Definition: maglev-ir.h:435
#define LOAD_CONSTANT_TYPED_ARRAY(name, properties,...)
#define ASSERT_CONDITION(V)
Definition: maglev-ir.h:6728
#define DEF_INT32_BINARY_NODE(Name)
Definition: maglev-ir.h:3217
#define CONSTANT_VALUE_NODE_LIST(V)
Definition: maglev-ir.h:145
unsigned short uint16_t
Definition: unicode.cc:41
int int32_t
Definition: unicode.cc:42
constexpr unsigned CountTrailingZerosNonZero(T value) requires(std
Definition: bits.h:173
constexpr int ClearLsb(T value) requires std
Definition: bits.h:295
auto make_iterator_range(ForwardIterator begin, ForwardIterator end)
Definition: iterator.h:65
size_t hash_value(unsigned long v)
Definition: hashing.h:209
size_t hash_combine(size_t seed, size_t hash)
Definition: hashing.h:77
V8_BASE_EXPORT int const char va_list args
Definition: strings.h:23
T Divide(T x, T y)
void Add(RWDigits Z, Digits X, Digits Y)
void Subtract(RWDigits Z, Digits X, Digits Y)
Maybe< int > OffsetOfElementAt(ElementAccess const &access, int index)
FloatWithBits< 64 > Float64
Definition: index.h:240
Node::Uses::const_iterator end(const Node::Uses &uses)
Definition: node.h:711
Node::Uses::const_iterator begin(const Node::Uses &uses)
Definition: node.h:708
constexpr T * ObjectPtrBeforeAddress(void *address)
Definition: maglev-ir.h:2055
UINT32_ELEMENTS INT32_ELEMENTS FLOAT32_ELEMENTS
Definition: maglev-ir.h:8756
static constexpr NodeIdT kInvalidNodeId
Definition: maglev-ir.h:1096
constexpr bool IsControlNode(Opcode opcode)
Definition: maglev-ir.h:545
std::underlying_type_t< NodeType > NodeTypeInt
Definition: maglev-ir.h:710
static constexpr Opcode kLastNodeOpcode
Definition: maglev-ir.h:479
constexpr Condition ConditionForNaN()
static constexpr Opcode kLastOpcode
Definition: maglev-ir.h:456
NodeType StaticTypeForConstant(compiler::JSHeapBroker *broker, compiler::ObjectRef ref)
Definition: maglev-ir.h:879
static constexpr Opcode kLastGapMoveNodeOpcode
Definition: maglev-ir.h:475
requires(FloatType==ValueRepresentation::kFloat64||FloatType==ValueRepresentation::kHoleyFloat64) void CheckedNumberOrOddballToFloat64OrHoleyFloat64< Derived
static constexpr Opcode kFirstUnconditionalControlNodeOpcode
Definition: maglev-ir.h:493
bool HasOnlyStringMaps(base::Vector< const compiler::MapRef > maps)
Definition: maglev-ir.h:1070
base::EnumSet< UseRepresentation, int8_t > UseRepresentationSet
Definition: maglev-ir.h:9835
static constexpr int kOpcodeCount
Definition: maglev-ir.h:454
base::EnumSet< ValueRepresentation, int8_t > ValueRepresentationSet
Definition: maglev-ir.h:9834
static constexpr Opcode kLastControlNodeOpcode
Definition: maglev-ir.h:503
bool IsInstanceOfLeafNodeType(compiler::MapRef map, NodeType type, compiler::JSHeapBroker *broker)
Definition: maglev-ir.h:893
constexpr Condition ConditionFor(Operation operation)
static constexpr Opcode kFirstNodeOpcode
Definition: maglev-ir.h:478
constexpr NodeType EmptyNodeType()
Definition: maglev-ir.h:729
constexpr bool IsTerminalControlNode(Opcode opcode)
Definition: maglev-ir.h:560
constexpr NodeType UnionType(NodeType left, NodeType right)
Definition: maglev-ir.h:737
FixedInputNodeTMixin< InputCount, ValueNodeT< Derived >, Derived > FixedInputValueNodeT
Definition: maglev-ir.h:3054
UINT32_ELEMENTS INT8_ELEMENTS
Definition: maglev-ir.h:8747
bool HasOnlyNumberMaps(base::Vector< const compiler::MapRef > maps)
Definition: maglev-ir.h:1077
constexpr bool NodeTypeIs(NodeType type, NodeType to_check)
Definition: maglev-ir.h:743
constexpr bool IsZeroCostNode(Opcode opcode)
Definition: maglev-ir.h:532
constexpr bool IsEmptyNodeType(NodeType type)
Definition: maglev-ir.h:874
static constexpr Opcode kLastConstantNodeOpcode
Definition: maglev-ir.h:471
bool HasOnlyJSTypedArrayMaps(base::Vector< const compiler::MapRef > maps)
Definition: maglev-ir.h:1049
static constexpr Opcode kFirstGapMoveNodeOpcode
Definition: maglev-ir.h:473
constexpr OpProperties StaticPropertiesForOpcode(Opcode opcode)
Definition: maglev-ir.h:11851
static constexpr Opcode kLastTerminalControlNodeOpcode
Definition: maglev-ir.h:496
constexpr NodeType IntersectType(NodeType left, NodeType right)
Definition: maglev-ir.h:731
constexpr bool NodeTypeIsUnstable(NodeType type)
Definition: maglev-ir.h:756
const char * OpcodeToString(Opcode opcode)
Definition: maglev-ir.cc:52
bool IsInitializingOrTransitioning(StoreTaggedMode mode)
Definition: maglev-ir.h:9006
constexpr NodeType MakeTypeStable(NodeType type)
Definition: maglev-ir.h:797
constexpr bool IsConstantNode(Opcode opcode)
Definition: maglev-ir.h:510
static constexpr Opcode kLastConditionalControlNodeOpcode
Definition: maglev-ir.h:488
static constexpr NodeIdT kFirstValidNodeId
Definition: maglev-ir.h:1097
UINT32_ELEMENTS INT16_ELEMENTS
Definition: maglev-ir.h:8747
void CheckValueInputIs(const NodeBase *node, int i, ValueRepresentation expected, MaglevGraphLabeller *graph_labeller)
Definition: maglev-ir.cc:856
constexpr bool IsZeroExtendedRepresentation(ValueRepresentation repr)
Definition: maglev-ir.h:624
constexpr bool IsValueNode(Opcode opcode)
Definition: maglev-ir.h:507
DEFINE_TRUNCATE_NODE(TruncateFloat64ToInt32, HoleyFloat64, OpProperties::Int32()) DEFINE_TRUNCATE_NODE(UnsafeTruncateFloat64ToInt32
static constexpr int kNumAssertConditions
Definition: maglev-ir.h:6745
static constexpr Opcode kLastBranchControlNodeOpcode
Definition: maglev-ir.h:483
static constexpr Opcode kLastValueNodeOpcode
Definition: maglev-ir.h:467
constexpr bool IsCommutativeNode(Opcode opcode)
Definition: maglev-ir.h:514
static constexpr Opcode kFirstValueNodeOpcode
Definition: maglev-ir.h:465
bool IsInstanceOfNodeType(compiler::MapRef map, NodeType type, compiler::JSHeapBroker *broker)
Definition: maglev-ir.h:946
bool FromConstantToBool(LocalIsolate *local_isolate, ValueNode *node)
Definition: maglev-ir.cc:365
static constexpr Opcode kFirstControlNodeOpcode
Definition: maglev-ir.h:501
constexpr bool IsConditionalControlNode(Opcode opcode)
Definition: maglev-ir.h:552
std::ostream & operator<<(std::ostream &os, const PrintNode &printer)
constexpr bool IsDoubleRepresentation(ValueRepresentation repr)
Definition: maglev-ir.h:619
constexpr bool IsSimpleFieldStore(Opcode opcode)
Definition: maglev-ir.h:566
NodeType StaticTypeForMap(compiler::MapRef map, compiler::JSHeapBroker *broker)
Definition: maglev-ir.h:842
constexpr bool CanBeStoreToNonEscapedObject(Opcode opcode)
Definition: maglev-ir.h:586
constexpr bool IsTypedArrayStore(Opcode opcode)
Definition: maglev-ir.h:581
static constexpr Opcode kFirstConstantNodeOpcode
Definition: maglev-ir.h:469
constexpr bool NodeTypeIsNeverStandalone(NodeType type)
Definition: maglev-ir.h:714
bool HasNumberMap(base::Vector< const compiler::MapRef > maps)
Definition: maglev-ir.h:1084
static constexpr Opcode kFirstOpcode
Definition: maglev-ir.h:455
static constexpr int kNumberOfLeafNodeTypes
Definition: maglev-ir.h:675
bool NodeTypeMayBeNullOrUndefined(NodeType type)
Definition: maglev-ir.h:1002
static constexpr Opcode kLastUnconditionalControlNodeOpcode
Definition: maglev-ir.h:491
constexpr bool IsBranchControlNode(Opcode opcode)
Definition: maglev-ir.h:548
bool HasOnlyJSArrayMaps(base::Vector< const compiler::MapRef > maps)
Definition: maglev-ir.h:1056
static constexpr Opcode kFirstTerminalControlNodeOpcode
Definition: maglev-ir.h:498
static constexpr Opcode kFirstBranchControlNodeOpcode
Definition: maglev-ir.h:481
constexpr bool NodeTypeCanBe(NodeType type, NodeType to_check)
Definition: maglev-ir.h:749
constexpr bool IsUnconditionalControlNode(Opcode opcode)
Definition: maglev-ir.h:556
constexpr bool IsGapMoveNode(Opcode opcode)
Definition: maglev-ir.h:542
bool HasOnlyJSObjectMaps(base::Vector< const compiler::MapRef > maps)
Definition: maglev-ir.h:1063
static constexpr Opcode kFirstConditionalControlNodeOpcode
Definition: maglev-ir.h:486
constexpr bool IsElementsArrayWrite(Opcode opcode)
Definition: maglev-ir.h:577
unsigned char * type
Definition: trace-event.h:457
constexpr Condition Negate(Condition cond)
typedef void(VECTORCALL PWasmOp)(const uint8_t *code
constexpr Register no_reg
Definition: register-arm.h:92
constexpr int kTaggedSize
Definition: globals.h:533
DwVfpRegister DoubleRegister
Definition: register-arm.h:192
static constexpr DoubleRegList kEmptyDoubleRegList
Definition: reglist.h:40
Tagged(T object) -> Tagged< T >
RegListBase< Register > RegList
Definition: reglist-arm.h:14
RegListBase< DoubleRegister > DoubleRegList
Definition: reglist-arm.h:15
else if(instr->arch_opcode()==kRiscvCmpZero)
DCHECK(IsNull(value)||IsNativeContext(value)||value==Smi::uninitialized_deserialization_value())
@ kExternalFloat64Array
Definition: globals.h:2473
@ kExternalInt32Array
Definition: globals.h:2469
@ kExternalInt8Array
Definition: globals.h:2465
@ kExternalInt16Array
Definition: globals.h:2467
return value
Definition: map-inl.h:912
static constexpr RegList kEmptyRegList
Definition: reglist.h:33
constexpr int kMaxInt
Definition: globals.h:375
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset prototype
Definition: map-inl.h:69
constexpr int MB
Definition: v8-internal.h:56
constexpr bool PointerCompressionIsEnabled()
Definition: v8-internal.h:192
!IsContextMap !IsContextMap native_context
Definition: map-inl.h:896
This file provides additional API on top of the default one for making API calls, which come from emb...
#define UNARY_OPERATION_LIST(V)
Definition: operation.h:24
std::ostream & operator<<(std::ostream &os, const Operation &operation)
Definition: operation.h:49
#define ARITHMETIC_OPERATION_LIST(V)
Definition: operation.h:10
#define COMPARISON_OPERATION_LIST(V)
Definition: operation.h:30
#define UNREACHABLE()
Definition: logging.h:67
#define DCHECK_LE(v1, v2)
Definition: logging.h:489
#define DCHECK_NULL(val)
Definition: logging.h:490
#define CHECK(condition)
Definition: logging.h:124
#define DCHECK_NOT_NULL(val)
Definition: logging.h:491
#define DCHECK_IMPLIES(v1, v2)
Definition: logging.h:492
#define DCHECK_NE(v1, v2)
Definition: logging.h:485
#define DCHECK_GE(v1, v2)
Definition: logging.h:487
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition: logging.h:481
#define DCHECK_LT(v1, v2)
Definition: logging.h:488
#define DCHECK_EQ(v1, v2)
Definition: logging.h:484
#define DCHECK_GT(v1, v2)
Definition: logging.h:486
#define USE(...)
Definition: macros.h:293
constexpr bool IsAligned(T value, U alignment)
Definition: macros.h:403
const CompactInterpreterFrameState * frame_state
Definition: maglev-ir.h:1522
BasicBlock * operator=(BasicBlock *owner)
Definition: maglev-ir.h:2504
compiler::FixedDoubleArrayRef values
Definition: maglev-ir.h:6134